Compare commits
13 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c2601ba69c | |||
| 344e9c55ab | |||
| 9c3213ebac | |||
| 2a55ff522e | |||
| 18021a32e4 | |||
| dfcbef81ef | |||
| b3119f5287 | |||
| dacb2e3046 | |||
| baea567f24 | |||
| 2484f6a598 | |||
| c946642873 | |||
| 03330973d7 | |||
| d71997a508 |
29 changed files with 479 additions and 60 deletions
2
dev/dev.mjs
Normal file
2
dev/dev.mjs
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
// Hooks
|
||||||
|
import "./hooks/ready.mjs";
|
||||||
5
dev/hooks/ready.mjs
Normal file
5
dev/hooks/ready.mjs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { __ID__ } from "../../module/consts.mjs";
|
||||||
|
|
||||||
|
Hooks.on(`ready`, () => {
|
||||||
|
console.table(game.modules.get(__ID__).api.settings);
|
||||||
|
});
|
||||||
|
|
@ -9,6 +9,10 @@
|
||||||
"name": "Auto Unpause On Load",
|
"name": "Auto Unpause On Load",
|
||||||
"hint": "(v13+, GM-Only) Automatically unpauses the game when you load into the world. This will happen EVERY time you load into the world, including if you reload the website."
|
"hint": "(v13+, GM-Only) Automatically unpauses the game when you load into the world. This will happen EVERY time you load into the world, including if you reload the website."
|
||||||
},
|
},
|
||||||
|
"chatImageLinks": {
|
||||||
|
"name": "Image Shortcuts",
|
||||||
|
"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",
|
||||||
"hint": "(v13+) Adds a background to the chat tab of the right-hand sidebar."
|
"hint": "(v13+) Adds a background to the chat tab of the right-hand sidebar."
|
||||||
|
|
@ -21,9 +25,17 @@
|
||||||
"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": {
|
||||||
|
"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."
|
||||||
|
},
|
||||||
"preventUserConfigOpen": {
|
"preventUserConfigOpen": {
|
||||||
"name": "Prevent Auto User Config",
|
"name": "Prevent Auto User Config",
|
||||||
"hint": "(v13+) Prevents Foundry from opening the User Configuration when a player loads into the world."
|
"hint": "(v13+, Non-GMs) Prevents Foundry from opening the User Configuration when a player loads into the world."
|
||||||
},
|
},
|
||||||
"repositionHotbar": {
|
"repositionHotbar": {
|
||||||
"name": "Reposition Hotbar",
|
"name": "Reposition Hotbar",
|
||||||
|
|
@ -46,11 +58,25 @@
|
||||||
"name": "Developer Settings",
|
"name": "Developer Settings",
|
||||||
"hint": "Tweaks that are relevant if you are developing something within Foundry, but are rarely useful outside of that context.",
|
"hint": "Tweaks that are relevant if you are developing something within Foundry, but are rarely useful outside of that context.",
|
||||||
"label": "Configure Dev Settings"
|
"label": "Configure Dev Settings"
|
||||||
|
},
|
||||||
|
"hotbarSettings": {
|
||||||
|
"name": "Hotbar Settings",
|
||||||
|
"hint": "Tweaks that modify Foundry's hotbar",
|
||||||
|
"label": "Configure Hotbar"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"apps": {
|
"apps": {
|
||||||
"no-settings-to-display": "No settings to display",
|
"no-settings-to-display": "No settings to display",
|
||||||
"make-global-reference": "Make Global Reference"
|
"make-global-reference": "Make Global Reference"
|
||||||
|
},
|
||||||
|
"dialogs": {
|
||||||
|
"chatImageLinks": {
|
||||||
|
"didYouKnowImageLink": "",
|
||||||
|
"convertAndDontShowAgain": "",
|
||||||
|
"justConvert": "",
|
||||||
|
"ignoreAndDontShowAgain": "",
|
||||||
|
"disableEntirely": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "oft",
|
"id": "oft",
|
||||||
"title": "Oliver's Foundry Tweaks",
|
"title": "Oliver's Foundry Tweaks",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
{ "name": "Oliver" }
|
{ "name": "Oliver" }
|
||||||
],
|
],
|
||||||
|
|
@ -14,7 +14,8 @@
|
||||||
"maximum": 13
|
"maximum": 13
|
||||||
},
|
},
|
||||||
"esmodules": [
|
"esmodules": [
|
||||||
"module/oft.mjs"
|
"module/oft.mjs",
|
||||||
|
"dev/dev.mjs"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { devSettings } from "../utils/DevSettings.mjs";
|
import { categories } from "../utils/SubMenuSettings.mjs";
|
||||||
import { OFTSettingsMenu } from "./OFTSettingsMenu.mjs";
|
import { OFTSettingsMenu } from "./OFTSettingsMenu.mjs";
|
||||||
|
|
||||||
export class DevSettingsMenu extends OFTSettingsMenu {
|
export class DevSettingsMenu extends OFTSettingsMenu {
|
||||||
|
|
@ -9,6 +9,7 @@ export class DevSettingsMenu extends OFTSettingsMenu {
|
||||||
};
|
};
|
||||||
|
|
||||||
static get _SETTINGS() {
|
static get _SETTINGS() {
|
||||||
|
const devSettings = categories.get(`dev`);
|
||||||
const settingIDs = [];
|
const settingIDs = [];
|
||||||
for (const [settingID, shown] of devSettings.entries()) {
|
for (const [settingID, shown] of devSettings.entries()) {
|
||||||
if (shown) {
|
if (shown) {
|
||||||
|
|
|
||||||
21
module/apps/HotbarSettingsMenu.mjs
Normal file
21
module/apps/HotbarSettingsMenu.mjs
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { categories } from "../utils/SubMenuSettings.mjs";
|
||||||
|
import { OFTSettingsMenu } from "./OFTSettingsMenu.mjs";
|
||||||
|
|
||||||
|
export class HotbarSettingsMenu extends OFTSettingsMenu {
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
window: {
|
||||||
|
title: `OFT.menu.hotbarSettings.name`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static get _SETTINGS() {
|
||||||
|
const settings = categories.get(`hotbar`);
|
||||||
|
const settingIDs = [];
|
||||||
|
for (const [settingID, shown] of settings.entries()) {
|
||||||
|
if (shown) {
|
||||||
|
settingIDs.push(settingID);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return settingIDs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { filePath } from "../consts.mjs";
|
import { __ID__, filePath } from "../consts.mjs";
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin: HAM, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin: HAM, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -7,6 +7,7 @@ export class OFTSettingsMenu extends HAM(ApplicationV2) {
|
||||||
// #region Options
|
// #region Options
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
tag: `form`,
|
tag: `form`,
|
||||||
|
classes: [ __ID__ ],
|
||||||
window: {
|
window: {
|
||||||
icon: `fa-solid fa-gears`,
|
icon: `fa-solid fa-gears`,
|
||||||
resizable: true,
|
resizable: true,
|
||||||
|
|
|
||||||
17
module/hooks/init.mjs
Normal file
17
module/hooks/init.mjs
Normal 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();
|
||||||
|
});
|
||||||
|
|
@ -5,7 +5,8 @@ of incompatabilities for whatever reason. This can also be used
|
||||||
internally within this module if we discover incompatabilites with
|
internally within this module if we discover incompatabilites with
|
||||||
systems and want to disable it on our side.
|
systems and want to disable it on our side.
|
||||||
|
|
||||||
This file is more as documentation than anything at this point in time.
|
This file is meant more documentation than anything at this point in
|
||||||
|
time.
|
||||||
|
|
||||||
Call Signature: (settingKey: string) => {}
|
Call Signature: (settingKey: string) => (void | boolean)
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
13
module/hooks/oft.settingStatuses.mjs
Normal file
13
module/hooks/oft.settingStatuses.mjs
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
This hook is used to enable any modules that attempt to disable settings
|
||||||
|
or just want to investigate what settings are enabled to be able to get
|
||||||
|
a ping with information about which settings where registered entirely
|
||||||
|
and which weren't. The object that is passed to this is frozen and is
|
||||||
|
not meant to be edited as you cannot de-register nor prevent setting
|
||||||
|
registration from this hook. For that see the "oft.preventSetting" hook.
|
||||||
|
|
||||||
|
This file is meant more documentation than anything at this point in
|
||||||
|
time.
|
||||||
|
|
||||||
|
Call Signature: (settings: Record<string, boolean>) => void
|
||||||
|
*/
|
||||||
58
module/hooks/setup.mjs
Normal file
58
module/hooks/setup.mjs
Normal 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,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,40 +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 { 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";
|
|
||||||
|
|
||||||
// Misc
|
|
||||||
import { __ID__ } from "./consts.mjs";
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
chatSidebarBackground();
|
|
||||||
startSidebarExpanded();
|
|
||||||
startingSidebarTab();
|
|
||||||
hotbarButtonSize();
|
|
||||||
hotbarButtonGap();
|
|
||||||
repositionHotbar();
|
|
||||||
preventUserConfigOpen();
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
|
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/DevSettings.mjs";
|
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,4 +35,5 @@ export function addGlobalDocReferrer() {
|
||||||
});
|
});
|
||||||
// #endregion Implementation
|
// #endregion Implementation
|
||||||
|
|
||||||
|
status[key] = SettingStatusEnum.Registered;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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";
|
||||||
import { registerDevSetting } from "../utils/DevSettings.mjs";
|
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`);
|
||||||
|
status[key] = SettingStatusEnum.Blocked;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -34,4 +37,6 @@ export function autoUnpauseOnLoad() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
// #endregion Implementation
|
// #endregion Implementation
|
||||||
|
|
||||||
|
status[key] = SettingStatusEnum.Registered;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
130
module/settings/chatImageLinks.mjs
Normal file
130
module/settings/chatImageLinks.mjs
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||||
|
import { __ID__ } from "../consts.mjs";
|
||||||
|
import { Logger } from "../utils/Logger.mjs";
|
||||||
|
|
||||||
|
const { DialogV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
const key = `chatImageLinks`;
|
||||||
|
const IMAGE_TYPES = [
|
||||||
|
`png`,
|
||||||
|
`jpg`,
|
||||||
|
`jpeg`,
|
||||||
|
`webp`,
|
||||||
|
`svg`,
|
||||||
|
];
|
||||||
|
|
||||||
|
export function chatImageLinks() {
|
||||||
|
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: `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
|
||||||
|
|
@ -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}`);
|
||||||
|
|
@ -28,4 +30,6 @@ export function chatSidebarBackground() {
|
||||||
document.body.classList.add(`${__ID__}-${key}`);
|
document.body.classList.add(`${__ID__}-${key}`);
|
||||||
};
|
};
|
||||||
// #endregion Implementation
|
// #endregion Implementation
|
||||||
|
|
||||||
|
status[key] = SettingStatusEnum.Registered;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,24 @@
|
||||||
|
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";
|
||||||
|
|
||||||
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`);
|
||||||
|
status[key] = SettingStatusEnum.Blocked;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
// #region Registration
|
// #region Registration
|
||||||
Logger.log(`Registering setting: ${key}`);
|
Logger.log(`Registering setting: ${key}`);
|
||||||
document.body.classList.add(`${__ID__}-${key}`);
|
document.body.classList.add(`${__ID__}-${key}`);
|
||||||
game.settings.register(__ID__, key, {
|
registerCategorySetting(`hotbar`, __ID__, key, {
|
||||||
name: `OFT.setting.${key}.name`,
|
name: `OFT.setting.${key}.name`,
|
||||||
hint: `OFT.setting.${key}.hint`,
|
hint: `OFT.setting.${key}.hint`,
|
||||||
scope: `user`,
|
scope: `user`,
|
||||||
|
|
@ -36,4 +40,6 @@ export function hotbarButtonGap() {
|
||||||
const buttonGap = game.settings.get(__ID__, key);
|
const buttonGap = game.settings.get(__ID__, key);
|
||||||
document.body.style.setProperty(`--hotbar-button-gap`, `${buttonGap}px`);
|
document.body.style.setProperty(`--hotbar-button-gap`, `${buttonGap}px`);
|
||||||
// #endregion Implementation
|
// #endregion Implementation
|
||||||
|
|
||||||
|
status[key] = SettingStatusEnum.Registered;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,24 @@
|
||||||
|
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";
|
||||||
|
|
||||||
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`);
|
||||||
|
status[key] = SettingStatusEnum.Blocked;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
// #region Registration
|
// #region Registration
|
||||||
Logger.log(`Registering setting: ${key}`);
|
Logger.log(`Registering setting: ${key}`);
|
||||||
document.body.classList.add(`${__ID__}-${key}`);
|
document.body.classList.add(`${__ID__}-${key}`);
|
||||||
game.settings.register(__ID__, key, {
|
registerCategorySetting(`hotbar`, __ID__, key, {
|
||||||
name: `OFT.setting.${key}.name`,
|
name: `OFT.setting.${key}.name`,
|
||||||
hint: `OFT.setting.${key}.hint`,
|
hint: `OFT.setting.${key}.hint`,
|
||||||
scope: `user`,
|
scope: `user`,
|
||||||
|
|
@ -36,4 +40,6 @@ export function hotbarButtonSize() {
|
||||||
const hotbarSize = game.settings.get(__ID__, key);
|
const hotbarSize = game.settings.get(__ID__, key);
|
||||||
document.body.style.setProperty(`--hotbar-size`, `${hotbarSize}px`);
|
document.body.style.setProperty(`--hotbar-size`, `${hotbarSize}px`);
|
||||||
// #endregion Implementation
|
// #endregion Implementation
|
||||||
|
|
||||||
|
status[key] = SettingStatusEnum.Registered;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
42
module/settings/preventMovementHistory.mjs
Normal file
42
module/settings/preventMovementHistory.mjs
Normal 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;
|
||||||
|
};
|
||||||
53
module/settings/preventTokenRotation.mjs
Normal file
53
module/settings/preventTokenRotation.mjs
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||||
|
import { __ID__ } from "../consts.mjs";
|
||||||
|
import { Logger } from "../utils/Logger.mjs";
|
||||||
|
|
||||||
|
const key = `preventTokenRotation`;
|
||||||
|
|
||||||
|
export function preventTokenRotation() {
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @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
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
|
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`);
|
||||||
|
status[key] = SettingStatusEnum.Blocked;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -19,7 +22,7 @@ export function preventUserConfigOpen() {
|
||||||
scope: `user`,
|
scope: `user`,
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
config: true,
|
config: !game.user.isGM,
|
||||||
requiresReload: false,
|
requiresReload: false,
|
||||||
});
|
});
|
||||||
// #endregion Registration
|
// #endregion Registration
|
||||||
|
|
@ -32,4 +35,6 @@ export function preventUserConfigOpen() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
// #endregion Implementation
|
// #endregion Implementation
|
||||||
|
|
||||||
|
status[key] = SettingStatusEnum.Registered;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,23 @@
|
||||||
|
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";
|
||||||
|
|
||||||
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`);
|
||||||
|
status[key] = SettingStatusEnum.Blocked;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
// #region Registration
|
// #region Registration
|
||||||
Logger.log(`Registering setting: ${key}`);
|
Logger.log(`Registering setting: ${key}`);
|
||||||
game.settings.register(__ID__, key, {
|
registerCategorySetting(`hotbar`, __ID__, key, {
|
||||||
name: `OFT.setting.${key}.name`,
|
name: `OFT.setting.${key}.name`,
|
||||||
hint: `OFT.setting.${key}.hint`,
|
hint: `OFT.setting.${key}.hint`,
|
||||||
scope: `user`,
|
scope: `user`,
|
||||||
|
|
@ -42,4 +46,6 @@ export function repositionHotbar() {
|
||||||
uiPosition.insertAdjacentElement(`beforeend`, container);
|
uiPosition.insertAdjacentElement(`beforeend`, container);
|
||||||
};
|
};
|
||||||
// #endregion Implementation
|
// #endregion Implementation
|
||||||
|
|
||||||
|
status[key] = SettingStatusEnum.Registered;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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}`);
|
||||||
|
|
@ -26,4 +28,6 @@ export function startSidebarExpanded() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
// #endregion Implementation
|
// #endregion Implementation
|
||||||
|
|
||||||
|
status[key] = SettingStatusEnum.Registered;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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}`);
|
||||||
|
|
@ -42,10 +44,19 @@ export function startingSidebarTab() {
|
||||||
// #region Implementation
|
// #region Implementation
|
||||||
Hooks.once(`ready`, () => {
|
Hooks.once(`ready`, () => {
|
||||||
const defaultTab = game.settings.get(__ID__, key);
|
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) {
|
if (defaultTab) {
|
||||||
Logger.debug(`Changing tab to:`, defaultTab);
|
Logger.debug(`Changing tab to:`, defaultTab);
|
||||||
ui.sidebar.changeTab(defaultTab, `primary`);
|
ui.sidebar.changeTab(defaultTab, `primary`);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
// #endregion Implementation
|
// #endregion Implementation
|
||||||
|
|
||||||
|
status[key] = SettingStatusEnum.Registered;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
/** @type {Map<string, boolean>} */
|
|
||||||
export const devSettings = new Map();
|
|
||||||
|
|
||||||
export function registerDevSetting(namespace, key, config) {
|
|
||||||
const visible = config.config;
|
|
||||||
config.config = false;
|
|
||||||
game.settings.register(namespace, key, config);
|
|
||||||
devSettings.set(`${namespace}.${key}`, visible);
|
|
||||||
};
|
|
||||||
11
module/utils/SettingStatus.mjs
Normal file
11
module/utils/SettingStatus.mjs
Normal 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 = {};
|
||||||
22
module/utils/SubMenuSettings.mjs
Normal file
22
module/utils/SubMenuSettings.mjs
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
/** @type {Map<string, Map<string, boolean>>} */
|
||||||
|
export const categories = new Map();
|
||||||
|
|
||||||
|
export function registerCategorySetting(category, namespace, key, config) {
|
||||||
|
let cat = categories.get(category);
|
||||||
|
if (!cat) {
|
||||||
|
cat = new Map();
|
||||||
|
categories.set(category, cat);
|
||||||
|
};
|
||||||
|
const visible = config.config;
|
||||||
|
config.config = false;
|
||||||
|
game.settings.register(namespace, key, config);
|
||||||
|
cat.set(`${namespace}.${key}`, visible);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper function that registers the setting to the "dev"
|
||||||
|
* category
|
||||||
|
*/
|
||||||
|
export function registerDevSetting(namespace, key, config) {
|
||||||
|
registerCategorySetting(`dev`, namespace, key, config);
|
||||||
|
};
|
||||||
8
styles/apps.css
Normal file
8
styles/apps.css
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
.application.oft {
|
||||||
|
> .window-content.standard-form .setting-list {
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,5 +3,7 @@
|
||||||
@import url("./hotbarButtonSize.css");
|
@import url("./hotbarButtonSize.css");
|
||||||
@import url("./repositionHotbar.css");
|
@import url("./repositionHotbar.css");
|
||||||
|
|
||||||
|
@import url("./apps.css");
|
||||||
|
|
||||||
/* Make the chat sidebar the same width as all the other tabs */
|
/* Make the chat sidebar the same width as all the other tabs */
|
||||||
.chat-sidebar:not(.sidebar-popout) { width: unset; }
|
.chat-sidebar:not(.sidebar-popout) { width: unset; }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue