Add better status indicators, and a setting to prevent movement history recording

This commit is contained in:
Oliver 2025-12-13 21:31:56 -07:00
parent 344e9c55ab
commit c2601ba69c
18 changed files with 183 additions and 79 deletions

View file

@ -1,5 +1,5 @@
import { __ID__ } from "../../module/consts.mjs"; import { __ID__ } from "../../module/consts.mjs";
Hooks.on(`ready`, () => { Hooks.on(`ready`, () => {
console.table(game.modules.get(__ID__).api.registered); console.table(game.modules.get(__ID__).api.settings);
}); });

View file

@ -11,7 +11,7 @@
}, },
"chatImageLinks": { "chatImageLinks": {
"name": "Image Shortcuts", "name": "Image Shortcuts",
"hint": "When attempting to send an image/gif in chat, this allows you to easily embed the actual image in the text by changing \"http\"/\"https\" into \"image\", automatically displaying the image after sending the message." "hint": "(v13+) When attempting to send an image/gif in chat, this allows you to easily embed the actual image in the text by changing \"http\"/\"https\" into \"image\", automatically displaying the image after sending the message."
}, },
"chatSidebarBackground": { "chatSidebarBackground": {
"name": "Chat Background", "name": "Chat Background",
@ -25,6 +25,10 @@
"name": "Hotbar Button Size", "name": "Hotbar Button Size",
"hint": "(v13+) Changes the size of the hotbar buttons to a size you prefer." "hint": "(v13+) Changes the size of the hotbar buttons to a size you prefer."
}, },
"preventMovementHistory": {
"name": "Prevent Movement History",
"hint": "(v13+, GM-Only) This prevents Foundry from recording movement history of a token, but not disabling the movement ruler."
},
"preventTokenRotation": { "preventTokenRotation": {
"name": "Prevent Token Auto-Rotation", "name": "Prevent Token Auto-Rotation",
"hint": "(v13+, GM-Only) This prevents tokens from rotating while you are moving them allowing you to more easily use POG-style tokens without them being rotated automatically by Foundry." "hint": "(v13+, GM-Only) This prevents tokens from rotating while you are moving them allowing you to more easily use POG-style tokens without them being rotated automatically by Foundry."

17
module/hooks/init.mjs Normal file
View file

@ -0,0 +1,17 @@
// Settings
import { preventMovementHistory } from "../settings/preventMovementHistory.mjs";
// Utils
import { Logger } from "../utils/Logger.mjs";
/*
This is only here for setting that **require** being registered during
initialization due to documentClass changes. If there is any way that
these settings can be implemented to work during the setup hook, that is
where they ideally should be implemented.
*/
Hooks.on(`init`, () => {
Logger.log(`Initializing`);
preventMovementHistory();
});

58
module/hooks/setup.mjs Normal file
View file

@ -0,0 +1,58 @@
// Settings
import { addGlobalDocReferrer } from "../settings/addGlobalDocReferrer.mjs";
import { autoUnpauseOnLoad } from "../settings/autoUnpauseOnLoad.mjs";
import { chatImageLinks } from "../settings/chatImageLinks.mjs";
import { chatSidebarBackground } from "../settings/chatSidebarBackground.mjs";
import { hotbarButtonGap } from "../settings/hotbarButtonGap.mjs";
import { hotbarButtonSize } from "../settings/hotbarButtonSize.mjs";
import { preventTokenRotation } from "../settings/preventTokenRotation.mjs";
import { preventUserConfigOpen } from "../settings/preventUserConfigOpen.mjs";
import { repositionHotbar } from "../settings/repositionHotbar.mjs";
import { startingSidebarTab } from "../settings/startingSidebarTab.mjs";
import { startSidebarExpanded } from "../settings/startSidebarExpanded.mjs";
// Apps
import { DevSettingsMenu } from "../apps/DevSettingsMenu.mjs";
import { HotbarSettingsMenu } from "../apps/HotbarSettingsMenu.mjs";
// Misc
import { __ID__ } from "../consts.mjs";
import { status } from "../utils/SettingStatus.mjs";
const { deepFreeze } = foundry.utils;
Hooks.on(`setup`, () => {
game.settings.registerMenu(__ID__, `devSettings`, {
name: `OFT.menu.devSettings.name`,
hint: `OFT.menu.devSettings.hint`,
label: `OFT.menu.devSettings.label`,
restricted: false,
type: DevSettingsMenu,
});
addGlobalDocReferrer();
autoUnpauseOnLoad();
game.settings.registerMenu(__ID__, `hotbarSettings`, {
name: `OFT.menu.hotbarSettings.name`,
hint: `OFT.menu.hotbarSettings.hint`,
label: `OFT.menu.hotbarSettings.label`,
restricted: false,
type: HotbarSettingsMenu,
});
hotbarButtonSize();
hotbarButtonGap();
repositionHotbar();
chatImageLinks();
chatSidebarBackground();
startSidebarExpanded();
startingSidebarTab();
preventTokenRotation();
preventUserConfigOpen();
Hooks.callAll(`oft.settingStatuses`, deepFreeze(status));
game.modules.get(__ID__).api = deepFreeze({
settings: status,
});
});

View file

@ -1,61 +1,4 @@
// Hooks // Hooks
import "./hooks/init.mjs";
import "./hooks/setup.mjs";
import "./hooks/renderSettingsConfig.mjs"; import "./hooks/renderSettingsConfig.mjs";
// Settings
import { addGlobalDocReferrer } from "./settings/addGlobalDocReferrer.mjs";
import { autoUnpauseOnLoad } from "./settings/autoUnpauseOnLoad.mjs";
import { chatSidebarBackground } from "./settings/chatSidebarBackground.mjs";
import { hotbarButtonGap } from "./settings/hotbarButtonGap.mjs";
import { hotbarButtonSize } from "./settings/hotbarButtonSize.mjs";
import { preventTokenRotation } from "./settings/preventTokenRotation.mjs";
import { preventUserConfigOpen } from "./settings/preventUserConfigOpen.mjs";
import { repositionHotbar } from "./settings/repositionHotbar.mjs";
import { startingSidebarTab } from "./settings/startingSidebarTab.mjs";
import { startSidebarExpanded } from "./settings/startSidebarExpanded.mjs";
// Apps
import { DevSettingsMenu } from "./apps/DevSettingsMenu.mjs";
import { HotbarSettingsMenu } from "./apps/HotbarSettingsMenu.mjs";
// Misc
import { __ID__ } from "./consts.mjs";
import { chatImageLinks } from "./settings/chatImageLinks.mjs";
const { deepFreeze } = foundry.utils;
const status = {};
Hooks.on(`setup`, () => {
game.settings.registerMenu(__ID__, `devSettings`, {
name: `OFT.menu.devSettings.name`,
hint: `OFT.menu.devSettings.hint`,
label: `OFT.menu.devSettings.label`,
restricted: false,
type: DevSettingsMenu,
});
status.addGlobalDocReferrer = addGlobalDocReferrer();
status.autoUnpauseOnLoad = autoUnpauseOnLoad();
game.settings.registerMenu(__ID__, `hotbarSettings`, {
name: `OFT.menu.hotbarSettings.name`,
hint: `OFT.menu.hotbarSettings.hint`,
label: `OFT.menu.hotbarSettings.label`,
restricted: false,
type: HotbarSettingsMenu,
});
status.hotbarButtonSize = hotbarButtonSize();
status.hotbarButtonGap = hotbarButtonGap();
status.repositionHotbar = repositionHotbar();
status.chatImageLinks = chatImageLinks();
status.chatSidebarBackground = chatSidebarBackground();
status.startSidebarExpanded = startSidebarExpanded();
status.startingSidebarTab = startingSidebarTab();
status.preventTokenRotation = preventTokenRotation();
status.preventUserConfigOpen = preventUserConfigOpen();
Hooks.callAll(`oft.settingStatuses`, deepFreeze(status));
game.modules.get(__ID__).api = deepFreeze({
registered: status,
});
});

View file

@ -1,3 +1,4 @@
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
import { __ID__ } from "../consts.mjs"; import { __ID__ } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
import { registerDevSetting } from "../utils/SubMenuSettings.mjs"; import { registerDevSetting } from "../utils/SubMenuSettings.mjs";
@ -5,6 +6,7 @@ import { registerDevSetting } from "../utils/SubMenuSettings.mjs";
const key = `addGlobalDocReferrer`; const key = `addGlobalDocReferrer`;
export function addGlobalDocReferrer() { export function addGlobalDocReferrer() {
status[key] = SettingStatusEnum.Unknown;
// #region Registration // #region Registration
Logger.log(`Registering setting: ${key}`); Logger.log(`Registering setting: ${key}`);
@ -33,5 +35,5 @@ export function addGlobalDocReferrer() {
}); });
// #endregion Implementation // #endregion Implementation
return true; status[key] = SettingStatusEnum.Registered;
}; };

View file

@ -1,3 +1,4 @@
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
import { __ID__ } from "../consts.mjs"; import { __ID__ } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
import { registerDevSetting } from "../utils/SubMenuSettings.mjs"; import { registerDevSetting } from "../utils/SubMenuSettings.mjs";
@ -5,11 +6,13 @@ import { registerDevSetting } from "../utils/SubMenuSettings.mjs";
const key = `autoUnpauseOnLoad`; const key = `autoUnpauseOnLoad`;
export function autoUnpauseOnLoad() { export function autoUnpauseOnLoad() {
status[key] = SettingStatusEnum.Unknown;
const prevented = Hooks.call(`${__ID__}.preventSetting`, key); const prevented = Hooks.call(`${__ID__}.preventSetting`, key);
if (!prevented) { if (!prevented) {
Logger.log(`Preventing setting "${key}" from being registered`); Logger.log(`Preventing setting "${key}" from being registered`);
return false; status[key] = SettingStatusEnum.Blocked;
return;
}; };
// #region Registration // #region Registration
@ -35,5 +38,5 @@ export function autoUnpauseOnLoad() {
}); });
// #endregion Implementation // #endregion Implementation
return true; status[key] = SettingStatusEnum.Registered;
}; };

View file

@ -1,3 +1,4 @@
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
import { __ID__ } from "../consts.mjs"; import { __ID__ } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
@ -13,11 +14,13 @@ const IMAGE_TYPES = [
]; ];
export function chatImageLinks() { export function chatImageLinks() {
status[key] = SettingStatusEnum.Unknown;
const prevented = Hooks.call(`${__ID__}.preventSetting`, key); const prevented = Hooks.call(`${__ID__}.preventSetting`, key);
if (!prevented) { if (!prevented) {
Logger.log(`Preventing setting "${key}" from being registered`); Logger.log(`Preventing setting "${key}" from being registered`);
return false; status[key] = SettingStatusEnum.Blocked;
return;
}; };
// #region Registration // #region Registration
@ -103,7 +106,7 @@ export function chatImageLinks() {
} }
// #endregion Implementation // #endregion Implementation
return true; status[key] = SettingStatusEnum.Registered;
}; };
// #region Helpers // #region Helpers

View file

@ -1,9 +1,11 @@
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
import { __ID__ } from "../consts.mjs"; import { __ID__ } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
const key = `chatSidebarBackground`; const key = `chatSidebarBackground`;
export function chatSidebarBackground() { export function chatSidebarBackground() {
status[key] = SettingStatusEnum.Unknown;
// #region Registration // #region Registration
Logger.log(`Registering setting: ${key}`); Logger.log(`Registering setting: ${key}`);
@ -29,5 +31,5 @@ export function chatSidebarBackground() {
}; };
// #endregion Implementation // #endregion Implementation
return true; status[key] = SettingStatusEnum.Registered;
}; };

View file

@ -1,3 +1,4 @@
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
import { __ID__ } from "../consts.mjs"; import { __ID__ } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
import { registerCategorySetting } from "../utils/SubMenuSettings.mjs"; import { registerCategorySetting } from "../utils/SubMenuSettings.mjs";
@ -5,11 +6,13 @@ import { registerCategorySetting } from "../utils/SubMenuSettings.mjs";
const key = `hotbarButtonGap`; const key = `hotbarButtonGap`;
export function hotbarButtonGap() { export function hotbarButtonGap() {
status[key] = SettingStatusEnum.Unknown;
const prevented = Hooks.call(`${__ID__}.preventSetting`, key); const prevented = Hooks.call(`${__ID__}.preventSetting`, key);
if (!prevented) { if (!prevented) {
Logger.log(`Preventing setting "${key}" from being registered`); Logger.log(`Preventing setting "${key}" from being registered`);
return false; status[key] = SettingStatusEnum.Blocked;
return;
}; };
// #region Registration // #region Registration
@ -38,5 +41,5 @@ export function hotbarButtonGap() {
document.body.style.setProperty(`--hotbar-button-gap`, `${buttonGap}px`); document.body.style.setProperty(`--hotbar-button-gap`, `${buttonGap}px`);
// #endregion Implementation // #endregion Implementation
return true; status[key] = SettingStatusEnum.Registered;
}; };

View file

@ -1,3 +1,4 @@
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
import { __ID__ } from "../consts.mjs"; import { __ID__ } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
import { registerCategorySetting } from "../utils/SubMenuSettings.mjs"; import { registerCategorySetting } from "../utils/SubMenuSettings.mjs";
@ -5,11 +6,13 @@ import { registerCategorySetting } from "../utils/SubMenuSettings.mjs";
const key = `hotbarButtonSize`; const key = `hotbarButtonSize`;
export function hotbarButtonSize() { export function hotbarButtonSize() {
status[key] = SettingStatusEnum.Unknown;
const prevented = Hooks.call(`${__ID__}.preventSetting`, key); const prevented = Hooks.call(`${__ID__}.preventSetting`, key);
if (!prevented) { if (!prevented) {
Logger.log(`Preventing setting "${key}" from being registered`); Logger.log(`Preventing setting "${key}" from being registered`);
return false; status[key] = SettingStatusEnum.Blocked;
return;
}; };
// #region Registration // #region Registration
@ -38,5 +41,5 @@ export function hotbarButtonSize() {
document.body.style.setProperty(`--hotbar-size`, `${hotbarSize}px`); document.body.style.setProperty(`--hotbar-size`, `${hotbarSize}px`);
// #endregion Implementation // #endregion Implementation
return true; status[key] = SettingStatusEnum.Registered;
}; };

View file

@ -0,0 +1,42 @@
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
import { __ID__ } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs";
const key = `preventMovementHistory`;
export function preventMovementHistory() {
status[key] = SettingStatusEnum.Unknown;
const prevented = Hooks.call(`${__ID__}.preventSetting`, key);
if (!prevented) {
Logger.log(`Preventing setting "${key}" from being registered`);
status[key] = SettingStatusEnum.Blocked;
return;
};
// #region Registration
Logger.log(`Registering setting: ${key}`);
game.settings.register(__ID__, key, {
name: `OFT.setting.${key}.name`,
hint: `OFT.setting.${key}.hint`,
scope: `world`,
type: Boolean,
default: false,
config: true,
reloadRequired: true,
});
// #endregion Registration
// #region Implementation
if (game.settings.get(__ID__, key)) {
class OFTTokenDocument extends CONFIG.Token.documentClass {
_shouldRecordMovementHistory() {
return false;
};
};
CONFIG.Token.documentClass = OFTTokenDocument;
};
// #endregion Implementation
status[key] = SettingStatusEnum.Registered;
};

View file

@ -1,14 +1,17 @@
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
import { __ID__ } from "../consts.mjs"; import { __ID__ } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
const key = `preventTokenRotation`; const key = `preventTokenRotation`;
export function preventTokenRotation() { export function preventTokenRotation() {
status[key] = SettingStatusEnum.Unknown;
const prevented = Hooks.call(`${__ID__}.preventSetting`, key); const prevented = Hooks.call(`${__ID__}.preventSetting`, key);
if (!prevented) { if (!prevented) {
Logger.log(`Preventing setting "${key}" from being registered`); Logger.log(`Preventing setting "${key}" from being registered`);
return false; status[key] = SettingStatusEnum.Blocked;
return;
}; };
/** @type {number|null} */ /** @type {number|null} */
@ -40,7 +43,7 @@ export function preventTokenRotation() {
}; };
// #endregion Implementation // #endregion Implementation
return true; status[key] = SettingStatusEnum.Registered;
}; };
// #region Helpers // #region Helpers

View file

@ -1,14 +1,17 @@
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
import { __ID__ } from "../consts.mjs"; import { __ID__ } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
const key = `preventUserConfigOpen`; const key = `preventUserConfigOpen`;
export function preventUserConfigOpen() { export function preventUserConfigOpen() {
status[key] = SettingStatusEnum.Unknown;
const prevented = Hooks.call(`${__ID__}.preventSetting`, key); const prevented = Hooks.call(`${__ID__}.preventSetting`, key);
if (!prevented) { if (!prevented) {
Logger.log(`Preventing setting "${key}" from being registered`); Logger.log(`Preventing setting "${key}" from being registered`);
return false; status[key] = SettingStatusEnum.Blocked;
return;
}; };
// #region Registration // #region Registration
@ -33,5 +36,5 @@ export function preventUserConfigOpen() {
}); });
// #endregion Implementation // #endregion Implementation
return true; status[key] = SettingStatusEnum.Registered;
}; };

View file

@ -1,3 +1,4 @@
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
import { __ID__ } from "../consts.mjs"; import { __ID__ } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
import { registerCategorySetting } from "../utils/SubMenuSettings.mjs"; import { registerCategorySetting } from "../utils/SubMenuSettings.mjs";
@ -5,11 +6,13 @@ import { registerCategorySetting } from "../utils/SubMenuSettings.mjs";
const key = `repositionHotbar`; const key = `repositionHotbar`;
export function repositionHotbar() { export function repositionHotbar() {
status[key] = SettingStatusEnum.Unknown;
const prevented = Hooks.call(`${__ID__}.preventSetting`, key); const prevented = Hooks.call(`${__ID__}.preventSetting`, key);
if (!prevented) { if (!prevented) {
Logger.log(`Preventing setting "${key}" from being registered`); Logger.log(`Preventing setting "${key}" from being registered`);
return false; status[key] = SettingStatusEnum.Blocked;
return;
}; };
// #region Registration // #region Registration
@ -44,5 +47,5 @@ export function repositionHotbar() {
}; };
// #endregion Implementation // #endregion Implementation
return true; status[key] = SettingStatusEnum.Registered;
}; };

View file

@ -1,9 +1,11 @@
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
import { __ID__ } from "../consts.mjs"; import { __ID__ } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
const key = `startSidebarExpanded`; const key = `startSidebarExpanded`;
export function startSidebarExpanded() { export function startSidebarExpanded() {
status[key] = SettingStatusEnum.Unknown;
// #region Registration // #region Registration
Logger.log(`Registering setting: ${key}`); Logger.log(`Registering setting: ${key}`);
@ -27,5 +29,5 @@ export function startSidebarExpanded() {
}); });
// #endregion Implementation // #endregion Implementation
return true; status[key] = SettingStatusEnum.Registered;
}; };

View file

@ -1,9 +1,11 @@
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
import { __ID__ } from "../consts.mjs"; import { __ID__ } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
const key = `startingSidebarTab`; const key = `startingSidebarTab`;
export function startingSidebarTab() { export function startingSidebarTab() {
status[key] = SettingStatusEnum.Unknown;
// #region Registration // #region Registration
Logger.log(`Registering setting: ${key}`); Logger.log(`Registering setting: ${key}`);
@ -56,5 +58,5 @@ export function startingSidebarTab() {
}); });
// #endregion Implementation // #endregion Implementation
return true; status[key] = SettingStatusEnum.Registered;
}; };

View file

@ -0,0 +1,11 @@
/** @typedef {typeof SettingStatusEnum[keyof typeof SettingStatusEnum]} SettingStatus */
export const SettingStatusEnum = foundry.utils.deepFreeze({
Registered: `registered`,
Blocked: `blocked`,
Incompatible: `incompatible`,
Unknown: `unknown`,
});
/** @type {Record<string, SettingStatus>} */
export const status = {};