Move the tweak prevention into a helper function and rename the module hooks w/ compatibility code
This commit is contained in:
parent
3d4376aa81
commit
9c8b6f37f9
20 changed files with 102 additions and 102 deletions
41
module/tweaks/addGlobalDocReferrer.mjs
Normal file
41
module/tweaks/addGlobalDocReferrer.mjs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
import { registerDevSetting } from "../utils/SubMenuSettings.mjs";
|
||||
|
||||
const key = `addGlobalDocReferrer`;
|
||||
|
||||
export function addGlobalDocReferrer() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
// #region Registration
|
||||
Logger.log(`Registering setting: ${key}`);
|
||||
registerDevSetting(__ID__, key, {
|
||||
name: `OFT.setting.${key}.name`,
|
||||
hint: `OFT.setting.${key}.hint`,
|
||||
scope: `user`,
|
||||
type: Boolean,
|
||||
default: false,
|
||||
config: true,
|
||||
requiresReload: false,
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
Hooks.on(`getHeaderControlsDocumentSheetV2`, (app, controls) => {
|
||||
if (!game.settings.get(__ID__, key)) { return };
|
||||
|
||||
controls.push({
|
||||
icon: `fa-solid fa-file`,
|
||||
label: `OFT.apps.make-global-reference`,
|
||||
onClick: () => {
|
||||
globalThis._doc = app.document;
|
||||
},
|
||||
});
|
||||
});
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
37
module/tweaks/autoUnpauseOnLoad.mjs
Normal file
37
module/tweaks/autoUnpauseOnLoad.mjs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
import { registerDevSetting } from "../utils/SubMenuSettings.mjs";
|
||||
|
||||
const key = `autoUnpauseOnLoad`;
|
||||
|
||||
export function autoUnpauseOnLoad() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
// #region Registration
|
||||
Logger.log(`Registering setting: ${key}`);
|
||||
registerDevSetting(__ID__, key, {
|
||||
name: `OFT.setting.${key}.name`,
|
||||
hint: `OFT.setting.${key}.hint`,
|
||||
scope: `client`,
|
||||
type: Boolean,
|
||||
default: false,
|
||||
config: game.user.isGM,
|
||||
requiresReload: false,
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
Hooks.once(`ready`, () => {
|
||||
const autoUnpause = game.settings.get(__ID__, key);
|
||||
if (autoUnpause && game.paused) {
|
||||
Logger.debug(`setting:${key} | Unpausing the game`);
|
||||
game.togglePause(false, { broadcast: true });
|
||||
};
|
||||
});
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
125
module/tweaks/chatImageLinks.mjs
Normal file
125
module/tweaks/chatImageLinks.mjs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
|
||||
// const { DialogV2 } = foundry.applications.api;
|
||||
|
||||
const key = `chatImageLinks`;
|
||||
const IMAGE_TYPES = [
|
||||
`png`,
|
||||
`jpg`,
|
||||
`jpeg`,
|
||||
`webp`,
|
||||
`svg`,
|
||||
];
|
||||
|
||||
export function chatImageLinks() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
// #region Registration
|
||||
Logger.log(`Registering setting: ${key}`);
|
||||
game.settings.register(__ID__, key, {
|
||||
name: `OFT.setting.${key}.name`,
|
||||
hint: `OFT.setting.${key}.hint`,
|
||||
scope: `user`,
|
||||
type: Boolean,
|
||||
default: true,
|
||||
config: true,
|
||||
requiresReload: true,
|
||||
});
|
||||
|
||||
game.settings.register(__ID__, key + `-showPromptAgain`, {
|
||||
scope: `user`,
|
||||
type: Boolean,
|
||||
default: true,
|
||||
config: false,
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
if (game.settings.get(__ID__, key)) {
|
||||
Logger.log(`setting:${key} | Adding text enricher`);
|
||||
|
||||
// MARK: Enricher
|
||||
const pattern = new RegExp(
|
||||
`(?<!=|")(image:\\/\\/.*\\.(?:${IMAGE_TYPES.join(`|`)}))`,
|
||||
`gi`,
|
||||
);
|
||||
|
||||
CONFIG.TextEditor.enrichers.push({
|
||||
pattern,
|
||||
replaceParent: true,
|
||||
enricher: async (url) => {
|
||||
Logger.debug(url);
|
||||
url = url[0].replace(/^image:\/\//, ``);
|
||||
const secure = `https://${url}`;
|
||||
const insecure = `http://${url}`;
|
||||
|
||||
if (await isAcceptableImage(secure)) {
|
||||
const img = document.createElement(`img`);
|
||||
img.src = secure;
|
||||
img.alt = secure;
|
||||
return img;
|
||||
};
|
||||
|
||||
if (await isAcceptableImage(insecure)) {
|
||||
const img = document.createElement(`img`);
|
||||
img.src = insecure;
|
||||
img.alt = insecure;
|
||||
return img;
|
||||
};
|
||||
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
// MARK: Chat Input
|
||||
// Hooks.on(`chatMessage`, (chatLog, message, options) => {
|
||||
// if (!game.settings.get(__ID__, key)) { return };
|
||||
|
||||
// const match = message.match(pattern);
|
||||
// if (!match) { return };
|
||||
|
||||
// DialogV2.wait({
|
||||
// rejectClose: false,
|
||||
// content: game.i18n.localize(`OFT.dialogs.chatImageLinks.didYouKnowImageLink`),
|
||||
// buttons: [
|
||||
// { action: ``, label: `OFT.dialogs.chatImageLinks.convertAndDontShowAgain` },
|
||||
// { action: ``, label: `OFT.dialogs.chatImageLinks.justConvert` },
|
||||
// { action: ``, label: `OFT.dialogs.chatImageLinks.ignoreAndDontShowAgain` },
|
||||
// { action: ``, label: `OFT.dialogs.chatImageLinks.disableEntirely` },
|
||||
// ],
|
||||
// })
|
||||
// .then((selected) => {
|
||||
// chatLog.processMessage(message, options);
|
||||
// });
|
||||
|
||||
// return false;
|
||||
// });
|
||||
}
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
|
||||
// #region Helpers
|
||||
async function isAcceptableImage(url) {
|
||||
try {
|
||||
const response = await fetch(url, { method: `HEAD` });
|
||||
const contentType = response.headers.get(`Content-Type`);
|
||||
Logger.debug(`Image data:`, { url, contentType });
|
||||
let [ superType, subtype ] = contentType.split(`/`);
|
||||
if (superType !== `image`) {
|
||||
return false;
|
||||
};
|
||||
if (subtype.includes(`+`)) {
|
||||
subtype = subtype.split(`+`, 2).at(0);
|
||||
};
|
||||
return IMAGE_TYPES.includes(subtype);
|
||||
} catch {
|
||||
return false;
|
||||
};
|
||||
};
|
||||
// #endregion Helpers
|
||||
37
module/tweaks/chatSidebarBackground.mjs
Normal file
37
module/tweaks/chatSidebarBackground.mjs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
|
||||
const key = `chatSidebarBackground`;
|
||||
|
||||
export function chatSidebarBackground() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
// #region Registration
|
||||
Logger.log(`Registering setting: ${key}`);
|
||||
game.settings.register(__ID__, key, {
|
||||
name: `OFT.setting.${key}.name`,
|
||||
hint: `OFT.setting.${key}.hint`,
|
||||
scope: `user`,
|
||||
type: Boolean,
|
||||
default: true,
|
||||
config: true,
|
||||
requiresReload: false,
|
||||
onChange: (newValue) => {
|
||||
Logger.debug(`setting:${key} | Setting to ${newValue}`);
|
||||
document.body.classList.toggle(`${__ID__}-${key}`, newValue);
|
||||
},
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
if (game.settings.get(__ID__, key)) {
|
||||
Logger.debug(`setting:${key} | Adding chat background`);
|
||||
document.body.classList.add(`${__ID__}-${key}`);
|
||||
};
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
40
module/tweaks/hotbarButtonGap.mjs
Normal file
40
module/tweaks/hotbarButtonGap.mjs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
import { registerCategorySetting } from "../utils/SubMenuSettings.mjs";
|
||||
|
||||
const key = `hotbarButtonGap`;
|
||||
|
||||
export function hotbarButtonGap() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
// #region Registration
|
||||
Logger.log(`Registering setting: ${key}`);
|
||||
document.body.classList.add(`${__ID__}-${key}`);
|
||||
registerCategorySetting(`hotbar`, __ID__, key, {
|
||||
name: `OFT.setting.${key}.name`,
|
||||
hint: `OFT.setting.${key}.hint`,
|
||||
scope: `user`,
|
||||
type: new foundry.data.fields.NumberField({
|
||||
min: 0,
|
||||
max: 16,
|
||||
step: 1,
|
||||
}),
|
||||
default: 8,
|
||||
config: true,
|
||||
requiresReload: false,
|
||||
onChange: (newValue) => {
|
||||
document.body.style.setProperty(`--hotbar-button-gap`, `${newValue}px`);
|
||||
},
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
const buttonGap = game.settings.get(__ID__, key);
|
||||
document.body.style.setProperty(`--hotbar-button-gap`, `${buttonGap}px`);
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
40
module/tweaks/hotbarButtonSize.mjs
Normal file
40
module/tweaks/hotbarButtonSize.mjs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
import { registerCategorySetting } from "../utils/SubMenuSettings.mjs";
|
||||
|
||||
const key = `hotbarButtonSize`;
|
||||
|
||||
export function hotbarButtonSize() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
// #region Registration
|
||||
Logger.log(`Registering setting: ${key}`);
|
||||
document.body.classList.add(`${__ID__}-${key}`);
|
||||
registerCategorySetting(`hotbar`, __ID__, key, {
|
||||
name: `OFT.setting.${key}.name`,
|
||||
hint: `OFT.setting.${key}.hint`,
|
||||
scope: `user`,
|
||||
type: new foundry.data.fields.NumberField({
|
||||
min: 45,
|
||||
max: 75,
|
||||
step: 5,
|
||||
}),
|
||||
default: 60, // this is the value Foundry uses
|
||||
config: true,
|
||||
requiresReload: false,
|
||||
onChange: (newValue) => {
|
||||
document.body.style.setProperty(`--hotbar-size`, `${newValue}px`);
|
||||
},
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
const hotbarSize = game.settings.get(__ID__, key);
|
||||
document.body.style.setProperty(`--hotbar-size`, `${hotbarSize}px`);
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
37
module/tweaks/preventMovementHistory.mjs
Normal file
37
module/tweaks/preventMovementHistory.mjs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
|
||||
const key = `preventMovementHistory`;
|
||||
|
||||
export function preventMovementHistory() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { 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;
|
||||
};
|
||||
48
module/tweaks/preventTokenRotation.mjs
Normal file
48
module/tweaks/preventTokenRotation.mjs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
|
||||
const key = `preventTokenRotation`;
|
||||
|
||||
export function preventTokenRotation() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
/** @type {number|null} */
|
||||
let hookID = null;
|
||||
|
||||
// #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: true,
|
||||
config: true,
|
||||
requiresReload: false,
|
||||
onChange: (newValue) => {
|
||||
if (newValue) {
|
||||
hookID = Hooks.on(`preMoveToken`, preMoveTokenHandler);
|
||||
} else if (hookID != null) {
|
||||
Hooks.off(`preMoveToken`, hookID);
|
||||
};
|
||||
},
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
if (game.settings.get(__ID__, key)) {
|
||||
hookID = Hooks.on(`preMoveToken`, preMoveTokenHandler);
|
||||
};
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
|
||||
// #region Helpers
|
||||
function preMoveTokenHandler(_token, update) {
|
||||
update.autoRotate = false;
|
||||
};
|
||||
// #endregion Helpers
|
||||
35
module/tweaks/preventUserConfigOpen.mjs
Normal file
35
module/tweaks/preventUserConfigOpen.mjs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
|
||||
const key = `preventUserConfigOpen`;
|
||||
|
||||
export function preventUserConfigOpen() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
// #region Registration
|
||||
Logger.log(`Registering setting: ${key}`);
|
||||
game.settings.register(__ID__, key, {
|
||||
name: `OFT.setting.${key}.name`,
|
||||
hint: `OFT.setting.${key}.hint`,
|
||||
scope: `user`,
|
||||
type: Boolean,
|
||||
default: false,
|
||||
config: !game.user.isGM,
|
||||
requiresReload: false,
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
Hooks.once(`renderUserConfig`, (app, element) => {
|
||||
if (!game.ready && game.settings.get(__ID__, key)) {
|
||||
element.style.display = `none`;
|
||||
app.close();
|
||||
};
|
||||
});
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
46
module/tweaks/repositionHotbar.mjs
Normal file
46
module/tweaks/repositionHotbar.mjs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
import { registerCategorySetting } from "../utils/SubMenuSettings.mjs";
|
||||
|
||||
const key = `repositionHotbar`;
|
||||
|
||||
export function repositionHotbar() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
// #region Registration
|
||||
Logger.log(`Registering setting: ${key}`);
|
||||
registerCategorySetting(`hotbar`, __ID__, key, {
|
||||
name: `OFT.setting.${key}.name`,
|
||||
hint: `OFT.setting.${key}.hint`,
|
||||
scope: `user`,
|
||||
type: Boolean,
|
||||
default: true,
|
||||
config: true,
|
||||
requiresReload: true,
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
if (game.settings.get(__ID__, key)) {
|
||||
Logger.debug(`setting:${key} | Repositioning hotbar`);
|
||||
document.body.classList.add(`oft-${key}`);
|
||||
|
||||
const container = document.createElement(`div`);
|
||||
container.id = `oft-repositionHotbar-container`;
|
||||
|
||||
const playersPlaceholder = document.getElementById(`players`);
|
||||
const hotbarPlaceholder = document.getElementById(`hotbar`);
|
||||
|
||||
container.insertAdjacentElement(`afterbegin`, hotbarPlaceholder);
|
||||
container.insertAdjacentElement(`afterbegin`, playersPlaceholder);
|
||||
|
||||
const uiPosition = document.getElementById(`ui-left-column-1`);
|
||||
uiPosition.insertAdjacentElement(`beforeend`, container);
|
||||
};
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
35
module/tweaks/startSidebarExpanded.mjs
Normal file
35
module/tweaks/startSidebarExpanded.mjs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
|
||||
const key = `startSidebarExpanded`;
|
||||
|
||||
export function startSidebarExpanded() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
// #region Registration
|
||||
Logger.log(`Registering setting: ${key}`);
|
||||
game.settings.register(__ID__, key, {
|
||||
name: `OFT.setting.${key}.name`,
|
||||
hint: `OFT.setting.${key}.hint`,
|
||||
scope: `user`,
|
||||
type: Boolean,
|
||||
default: true,
|
||||
config: true,
|
||||
requiresReload: false,
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
Hooks.once(`renderSidebar`, (app) => {
|
||||
if (game.settings.get(__ID__, key) && !game.ready) {
|
||||
Logger.debug(`setting:${key} | Expanding sidebar`);
|
||||
app.toggleExpanded(true);
|
||||
};
|
||||
});
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
64
module/tweaks/startingSidebarTab.mjs
Normal file
64
module/tweaks/startingSidebarTab.mjs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
|
||||
const key = `startingSidebarTab`;
|
||||
|
||||
export function startingSidebarTab() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
// #region Registration
|
||||
Logger.log(`Registering setting: ${key}`);
|
||||
game.settings.register(__ID__, key, {
|
||||
name: `OFT.setting.${key}.name`,
|
||||
hint: `OFT.setting.${key}.hint`,
|
||||
type: new foundry.data.fields.StringField({
|
||||
blank: true,
|
||||
nullable: false,
|
||||
required: true,
|
||||
choices: () => {
|
||||
const tabs = Object.entries(CONFIG.ui.sidebar.TABS);
|
||||
|
||||
const tabChoices = {
|
||||
"": `OFT.setting.${key}.choices.blank`,
|
||||
};
|
||||
for (const [id, data] of tabs) {
|
||||
let { documentName, gmOnly, tooltip: name } = data;
|
||||
if (gmOnly && !game.user.isGM) { continue };
|
||||
|
||||
if (documentName) {
|
||||
name ??= foundry.utils.getDocumentClass(documentName).metadata.labelPlural;
|
||||
};
|
||||
|
||||
tabChoices[id] = name;
|
||||
};
|
||||
|
||||
return tabChoices;
|
||||
},
|
||||
}),
|
||||
config: true,
|
||||
requiresReload: false,
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
Hooks.once(`ready`, () => {
|
||||
const defaultTab = game.settings.get(__ID__, key);
|
||||
if (defaultTab === ``) { return };
|
||||
|
||||
if (!(defaultTab in CONFIG.ui.sidebar.TABS)) {
|
||||
Logger.error(`Failed to find starting tab with ID "${defaultTab}", skipping`);
|
||||
return;
|
||||
};
|
||||
|
||||
if (defaultTab) {
|
||||
Logger.debug(`Changing tab to:`, defaultTab);
|
||||
ui.sidebar.changeTab(defaultTab, `primary`);
|
||||
};
|
||||
});
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
122
module/tweaks/toggleMouseBroadcast.mjs
Normal file
122
module/tweaks/toggleMouseBroadcast.mjs
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
|
||||
const key = `toggleMouseBroadcast`;
|
||||
|
||||
/** @type {number | null} */
|
||||
let notifID = null;
|
||||
|
||||
export function toggleMouseBroadcast() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
// #region Registration
|
||||
Logger.log(`Registering setting: ${key}`);
|
||||
|
||||
// MARK: setting
|
||||
game.settings.register(__ID__, key, {
|
||||
scope: `client`,
|
||||
config: false,
|
||||
default: true,
|
||||
});
|
||||
|
||||
// MARK: keybind
|
||||
game.keybindings.register(__ID__, key, {
|
||||
name: `OFT.keybindings.${key}.name`,
|
||||
hint: `OFT.keybindings.${key}.hint`,
|
||||
precedence: CONST.KEYBINDING_PRECEDENCE.NORMAL,
|
||||
restricted: true,
|
||||
editable: [
|
||||
{ key: `KeyH` },
|
||||
],
|
||||
onDown: (event) => {
|
||||
if (!game.user.hasPermission(`SHOW_CURSOR`)) { return };
|
||||
event.preventDefault?.();
|
||||
const current = game.settings.get(__ID__, key);
|
||||
|
||||
if (current) {
|
||||
notifID = ui.notifications.warn(
|
||||
`OFT.notifs.${key}.hidingCursor`,
|
||||
{ console: false, localize: true, permanent: true },
|
||||
).id;
|
||||
} else {
|
||||
if (notifID != null) {
|
||||
ui.notifications.remove(notifID);
|
||||
notifID = null;
|
||||
};
|
||||
ui.notifications.success(
|
||||
`OFT.notifs.${key}.showingCursor`,
|
||||
{ console: false, localize: true },
|
||||
);
|
||||
};
|
||||
|
||||
game.settings.set(__ID__, key, !current);
|
||||
|
||||
// Hide the existing cursor
|
||||
game.user.broadcastActivity({ cursor: null });
|
||||
return true;
|
||||
},
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
Hooks.on(`renderControlsConfig`, renderControlsConfigHandler);
|
||||
Hooks.once(`ready`, readyHandler);
|
||||
|
||||
class OFTControlsLayer extends CONFIG.Canvas.layers.controls.layerClass {
|
||||
_onMouseMove(currentPos) {
|
||||
if (!game.settings.get(__ID__, key)) {
|
||||
game.user.broadcastActivity({});
|
||||
};
|
||||
super._onMouseMove(currentPos);
|
||||
};
|
||||
};
|
||||
CONFIG.Canvas.layers.controls.layerClass = OFTControlsLayer;
|
||||
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
|
||||
// #region Helpers
|
||||
const tabGroup = `categories`;
|
||||
|
||||
/**
|
||||
* Handle showing the "hiding your cursor" notification when the user
|
||||
* connects to the server initially, allowing the current state to be
|
||||
* correctly described to the user.
|
||||
*/
|
||||
function readyHandler() {
|
||||
const hideCursor = !game.settings.get(__ID__, key);
|
||||
const canShowCursor = game.user.hasPermission(`SHOW_CURSOR`);
|
||||
if (hideCursor && canShowCursor) {
|
||||
notifID = ui.notifications.warn(
|
||||
`OFT.notifs.${key}.hidingCursor`,
|
||||
{ console: false, localize: true, permanent: true },
|
||||
).id;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles hiding the keybinding from the configuration if and when the user
|
||||
* does not have the SHOW_CURSOR permission since this keybinding is really
|
||||
* useless if they can't even broadcast their cursor in the first place.
|
||||
*/
|
||||
function renderControlsConfigHandler(_app, element) {
|
||||
|
||||
if (game.user.hasPermission(`SHOW_CURSOR`)) { return };
|
||||
|
||||
const keybindingList = element.querySelector(`section[data-group="${tabGroup}"][data-tab="${__ID__}"]`);
|
||||
const tabButton = element.querySelector(`button[data-group="${tabGroup}"][data-tab="${__ID__}"]`);
|
||||
|
||||
const keybind = keybindingList.querySelector(`.form-group[data-action-id="${__ID__}.${key}"]`);
|
||||
keybind?.remove();
|
||||
|
||||
if (keybindingList.childElementCount === 0) {
|
||||
keybindingList.remove();
|
||||
tabButton.remove();
|
||||
};
|
||||
};
|
||||
// #endregion Helpers
|
||||
Loading…
Add table
Add a link
Reference in a new issue