diff --git a/docs/2_PLUGINS.md b/docs/2_PLUGINS.md
index 7b5e3e181..705ea89d6 100644
--- a/docs/2_PLUGINS.md
+++ b/docs/2_PLUGINS.md
@@ -26,10 +26,6 @@ export default definePlugin({
name: "Your Name",
},
],
- // Delete `patches` if you are not using code patches, as it will make
- // your plugin require restarts, and your stop() method will not be
- // invoked at all. The presence of the key in the object alone is
- // enough to trigger this behavior, even if the value is an empty array.
patches: [],
// Delete these two below if you are only using code patches
start() {},
diff --git a/src/Vencord.ts b/src/Vencord.ts
index 4c0d2a86f..76719e570 100644
--- a/src/Vencord.ts
+++ b/src/Vencord.ts
@@ -28,12 +28,12 @@ import "./utils/quickCss";
import "./webpack/patchWebpack";
import { showNotification } from "./api/Notifications";
-import { PlainSettings, Settings } from "./api/settings";
+import { PlainSettings, Settings } from "./api/Settings";
import { patches, PMLogger, startAllPlugins } from "./plugins";
import { localStorage } from "./utils/localStorage";
import { relaunch } from "./utils/native";
import { getCloudSettings, putCloudSettings } from "./utils/settingsSync";
-import { checkForUpdates, update,UpdateLogger } from "./utils/updater";
+import { checkForUpdates, update, UpdateLogger } from "./utils/updater";
import { onceReady } from "./webpack";
import { SettingsRouter } from "./webpack/common";
diff --git a/src/api/Commands/index.ts b/src/api/Commands/index.ts
index 3f639a18a..ef4db171c 100644
--- a/src/api/Commands/index.ts
+++ b/src/api/Commands/index.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { makeCodeblock } from "@utils/misc";
+import { makeCodeblock } from "@utils/text";
import { sendBotMessage } from "./commandHelpers";
import { ApplicationCommandInputType, ApplicationCommandOptionType, ApplicationCommandType, Argument, Command, CommandContext, Option } from "./types";
diff --git a/src/api/ContextMenu.ts b/src/api/ContextMenu.ts
index 4d1d577b4..f1ebfdbd9 100644
--- a/src/api/ContextMenu.ts
+++ b/src/api/ContextMenu.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import type { ReactElement } from "react";
type ContextMenuPatchCallbackReturn = (() => void) | void;
diff --git a/src/api/MessageEvents.ts b/src/api/MessageEvents.ts
index 50d8b2658..b597feacb 100644
--- a/src/api/MessageEvents.ts
+++ b/src/api/MessageEvents.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import { MessageStore } from "@webpack/common";
import type { Channel, Message } from "discord-types/general";
import type { Promisable } from "type-fest";
diff --git a/src/api/MessagePopover.ts b/src/api/MessagePopover.ts
index 85dff9cf5..3391cfb38 100644
--- a/src/api/MessagePopover.ts
+++ b/src/api/MessagePopover.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import { Channel, Message } from "discord-types/general";
import type { MouseEventHandler } from "react";
diff --git a/src/api/Notifications/NotificationComponent.tsx b/src/api/Notifications/NotificationComponent.tsx
index 542c29bbf..caa4b64ef 100644
--- a/src/api/Notifications/NotificationComponent.tsx
+++ b/src/api/Notifications/NotificationComponent.tsx
@@ -18,7 +18,7 @@
import "./styles.css";
-import { useSettings } from "@api/settings";
+import { useSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { classes } from "@utils/misc";
import { React, useEffect, useMemo, useState, useStateFromStores, WindowStore } from "@webpack/common";
diff --git a/src/api/Notifications/Notifications.tsx b/src/api/Notifications/Notifications.tsx
index 600ea63d1..602564671 100644
--- a/src/api/Notifications/Notifications.tsx
+++ b/src/api/Notifications/Notifications.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { Queue } from "@utils/Queue";
import { ReactDOM } from "@webpack/common";
import type { ReactNode } from "react";
diff --git a/src/api/Notifications/notificationLog.tsx b/src/api/Notifications/notificationLog.tsx
index 72f09ac2f..9535fb62c 100644
--- a/src/api/Notifications/notificationLog.tsx
+++ b/src/api/Notifications/notificationLog.tsx
@@ -17,10 +17,10 @@
*/
import * as DataStore from "@api/DataStore";
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { classNameFactory } from "@api/Styles";
-import { useAwaiter } from "@utils/misc";
import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
+import { useAwaiter } from "@utils/react";
import { Alerts, Button, Forms, moment, React, Text, Timestamp, useEffect, useReducer, useState } from "@webpack/common";
import { nanoid } from "nanoid";
import type { DispatchWithoutAction } from "react";
diff --git a/src/api/ServerList.ts b/src/api/ServerList.ts
index c98b1740c..480441391 100644
--- a/src/api/ServerList.ts
+++ b/src/api/ServerList.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
const logger = new Logger("ServerListAPI");
diff --git a/src/api/settings.ts b/src/api/Settings.ts
similarity index 99%
rename from src/api/settings.ts
rename to src/api/Settings.ts
index 2329f9451..e481e48c0 100644
--- a/src/api/settings.ts
+++ b/src/api/Settings.ts
@@ -18,7 +18,7 @@
import { debounce } from "@utils/debounce";
import { localStorage } from "@utils/localStorage";
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import { mergeDefaults } from "@utils/misc";
import { putCloudSettings } from "@utils/settingsSync";
import { DefinedSettings, OptionType, SettingsChecks, SettingsDefinition } from "@utils/types";
diff --git a/src/api/SettingsStore.ts b/src/api/SettingsStore.ts
index a5a0402cc..d9369a956 100644
--- a/src/api/SettingsStore.ts
+++ b/src/api/SettingsStore.ts
@@ -16,11 +16,11 @@
* along with this program. If not, see .
*/
-import Logger from "@utils/Logger";
-import { proxyLazy } from "@utils/proxyLazy";
+import { proxyLazy } from "@utils/lazy";
+import { Logger } from "@utils/Logger";
import { findModuleId, wreq } from "@webpack";
-import { Settings } from "./settings";
+import { Settings } from "./Settings";
interface Setting {
/**
diff --git a/src/components/ErrorBoundary.tsx b/src/components/ErrorBoundary.tsx
index c34b47d20..ea2e02b51 100644
--- a/src/components/ErrorBoundary.tsx
+++ b/src/components/ErrorBoundary.tsx
@@ -16,9 +16,9 @@
* along with this program. If not, see .
*/
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins";
-import { LazyComponent } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
import { React } from "@webpack/common";
import { ErrorCard } from "./ErrorCard";
diff --git a/src/components/PatchHelper.tsx b/src/components/PatchHelper.tsx
index 37782ef3f..6c95a8a2c 100644
--- a/src/components/PatchHelper.tsx
+++ b/src/components/PatchHelper.tsx
@@ -18,8 +18,8 @@
import { debounce } from "@utils/debounce";
import { Margins } from "@utils/margins";
-import { makeCodeblock } from "@utils/misc";
import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches";
+import { makeCodeblock } from "@utils/text";
import { ReplaceFn } from "@utils/types";
import { search } from "@webpack";
import { Button, Clipboard, Forms, Parser, React, Switch, Text, TextInput } from "@webpack/common";
diff --git a/src/components/PluginSettings/PluginModal.tsx b/src/components/PluginSettings/PluginModal.tsx
index 3c5fc78f2..c50287320 100644
--- a/src/components/PluginSettings/PluginModal.tsx
+++ b/src/components/PluginSettings/PluginModal.tsx
@@ -17,13 +17,14 @@
*/
import { generateId } from "@api/Commands";
-import { useSettings } from "@api/settings";
+import { useSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Flex } from "@components/Flex";
+import { proxyLazy } from "@utils/lazy";
import { Margins } from "@utils/margins";
-import { classes, LazyComponent } from "@utils/misc";
+import { classes } from "@utils/misc";
import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize } from "@utils/modal";
-import { proxyLazy } from "@utils/proxyLazy";
+import { LazyComponent } from "@utils/react";
import { OptionType, Plugin } from "@utils/types";
import { findByCode, findByPropsLazy } from "@webpack";
import { Button, FluxDispatcher, Forms, React, Text, Tooltip, UserStore, UserUtils } from "@webpack/common";
diff --git a/src/components/PluginSettings/index.tsx b/src/components/PluginSettings/index.tsx
index 5a367c8db..7679c0158 100644
--- a/src/components/PluginSettings/index.tsx
+++ b/src/components/PluginSettings/index.tsx
@@ -20,7 +20,7 @@ import "./styles.css";
import * as DataStore from "@api/DataStore";
import { showNotice } from "@api/Notices";
-import { useSettings } from "@api/settings";
+import { useSettings } from "@api/Settings";
import { classNameFactory } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary";
import { Flex } from "@components/Flex";
@@ -29,11 +29,12 @@ import { Badge } from "@components/PluginSettings/components";
import PluginModal from "@components/PluginSettings/PluginModal";
import { Switch } from "@components/Switch";
import { ChangeList } from "@utils/ChangeList";
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins";
-import { classes, LazyComponent, useAwaiter } from "@utils/misc";
+import { classes } from "@utils/misc";
import { openModalLazy } from "@utils/modal";
import { onlyOnce } from "@utils/onlyOnce";
+import { LazyComponent, useAwaiter } from "@utils/react";
import { Plugin } from "@utils/types";
import { findByCode, findByPropsLazy } from "@webpack";
import { Alerts, Button, Card, Forms, Parser, React, Select, Text, TextInput, Toasts, Tooltip } from "@webpack/common";
@@ -126,7 +127,7 @@ function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, onMouseLe
}
// if the plugin has patches, dont use stopPlugin/startPlugin. Wait for restart to apply changes.
- if (plugin.patches) {
+ if (plugin.patches?.length) {
settings.enabled = !wasEnabled;
onRestartNeeded(plugin.name);
return;
diff --git a/src/components/VencordSettings/CloudTab.tsx b/src/components/VencordSettings/CloudTab.tsx
index 3452cef5a..5e48a72d3 100644
--- a/src/components/VencordSettings/CloudTab.tsx
+++ b/src/components/VencordSettings/CloudTab.tsx
@@ -17,7 +17,7 @@
*/
import { showNotification } from "@api/Notifications";
-import { Settings, useSettings } from "@api/settings";
+import { Settings, useSettings } from "@api/Settings";
import { CheckedTextInput } from "@components/CheckedTextInput";
import ErrorBoundary from "@components/ErrorBoundary";
import { Link } from "@components/Link";
diff --git a/src/components/VencordSettings/ThemesTab.tsx b/src/components/VencordSettings/ThemesTab.tsx
index bbd4fa933..75fea349f 100644
--- a/src/components/VencordSettings/ThemesTab.tsx
+++ b/src/components/VencordSettings/ThemesTab.tsx
@@ -16,11 +16,11 @@
* along with this program. If not, see .
*/
-import { useSettings } from "@api/settings";
+import { useSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Link } from "@components/Link";
import { Margins } from "@utils/margins";
-import { useAwaiter } from "@utils/misc";
+import { useAwaiter } from "@utils/react";
import { findLazy } from "@webpack";
import { Card, Forms, React, TextArea } from "@webpack/common";
diff --git a/src/components/VencordSettings/Updater.tsx b/src/components/VencordSettings/Updater.tsx
index 6fec9e753..9345d272d 100644
--- a/src/components/VencordSettings/Updater.tsx
+++ b/src/components/VencordSettings/Updater.tsx
@@ -16,16 +16,17 @@
* along with this program. If not, see .
*/
-import { useSettings } from "@api/settings";
+import { useSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { ErrorCard } from "@components/ErrorCard";
import { Flex } from "@components/Flex";
import { handleComponentFailed } from "@components/handleComponentFailed";
import { Link } from "@components/Link";
import { Margins } from "@utils/margins";
-import { classes, useAwaiter } from "@utils/misc";
+import { classes } from "@utils/misc";
import { relaunch } from "@utils/native";
import { onlyOnce } from "@utils/onlyOnce";
+import { useAwaiter } from "@utils/react";
import { changes, checkForUpdates, getRepo, isNewer, update, updateError, UpdateLogger } from "@utils/updater";
import { Alerts, Button, Card, Forms, Parser, React, Switch, Toasts } from "@webpack/common";
diff --git a/src/components/VencordSettings/VencordTab.tsx b/src/components/VencordSettings/VencordTab.tsx
index 672e04ee4..8c71821dd 100644
--- a/src/components/VencordSettings/VencordTab.tsx
+++ b/src/components/VencordSettings/VencordTab.tsx
@@ -18,14 +18,15 @@
import { openNotificationLogModal } from "@api/Notifications/notificationLog";
-import { Settings, useSettings } from "@api/settings";
+import { Settings, useSettings } from "@api/Settings";
import { classNameFactory } from "@api/Styles";
import DonateButton from "@components/DonateButton";
import ErrorBoundary from "@components/ErrorBoundary";
import { ErrorCard } from "@components/ErrorCard";
import { Margins } from "@utils/margins";
-import { identity, useAwaiter } from "@utils/misc";
+import { identity } from "@utils/misc";
import { relaunch, showItemInFolder } from "@utils/native";
+import { useAwaiter } from "@utils/react";
import { Button, Card, Forms, React, Select, Slider, Switch } from "@webpack/common";
const cl = classNameFactory("vc-settings-");
diff --git a/src/debug/Tracer.ts b/src/debug/Tracer.ts
index 185915a97..4337e0019 100644
--- a/src/debug/Tracer.ts
+++ b/src/debug/Tracer.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
if (IS_DEV) {
var traces = {} as Record;
diff --git a/src/main/ipcMain.ts b/src/main/ipcMain.ts
index b734f36de..5fcf8b7df 100644
--- a/src/main/ipcMain.ts
+++ b/src/main/ipcMain.ts
@@ -44,7 +44,7 @@ export function readSettings() {
}
}
-export function getSettings(): typeof import("@api/settings").Settings {
+export function getSettings(): typeof import("@api/Settings").Settings {
try {
return JSON.parse(readSettings());
} catch {
diff --git a/src/plugins/anonymiseFileNames.ts b/src/plugins/anonymiseFileNames.ts
index 26c423c0a..0baf099d6 100644
--- a/src/plugins/anonymiseFileNames.ts
+++ b/src/plugins/anonymiseFileNames.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/apiBadges.tsx b/src/plugins/apiBadges.tsx
index aaa1860f3..d9e97b22f 100644
--- a/src/plugins/apiBadges.tsx
+++ b/src/plugins/apiBadges.tsx
@@ -22,7 +22,7 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Flex } from "@components/Flex";
import { Heart } from "@components/Heart";
import { Devs } from "@utils/constants";
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins";
import { closeModal, Modals, openModal } from "@utils/modal";
import definePlugin from "@utils/types";
diff --git a/src/plugins/betterFolders/FolderSideBar.tsx b/src/plugins/betterFolders/FolderSideBar.tsx
index 3e44a5806..7159f7eea 100644
--- a/src/plugins/betterFolders/FolderSideBar.tsx
+++ b/src/plugins/betterFolders/FolderSideBar.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { classNameFactory } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary";
import { findByPropsLazy, findStoreLazy } from "@webpack";
diff --git a/src/plugins/betterFolders/index.ts b/src/plugins/betterFolders/index.ts
index d0e61c0d2..d41ba75c7 100644
--- a/src/plugins/betterFolders/index.ts
+++ b/src/plugins/betterFolders/index.ts
@@ -18,7 +18,7 @@
import "./betterFolders.css";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findLazy, findStoreLazy } from "@webpack";
diff --git a/src/plugins/betterNotes.ts b/src/plugins/betterNotes.ts
index 41842590f..d9c5b45c3 100644
--- a/src/plugins/betterNotes.ts
+++ b/src/plugins/betterNotes.ts
@@ -16,9 +16,8 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
-import { makeLazy } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
export default definePlugin({
@@ -30,7 +29,7 @@ export default definePlugin({
{
find: "hideNote:",
all: true,
- predicate: makeLazy(() => Vencord.Settings.plugins.BetterNotesBox.hide),
+ predicate: () => Vencord.Settings.plugins.BetterNotesBox.hide,
replacement: {
match: /hideNote:.+?(?=[,}])/g,
replace: "hideNote:true",
diff --git a/src/plugins/betterRoleDot.ts b/src/plugins/betterRoleDot.ts
index 6e026c78e..773176d8e 100644
--- a/src/plugins/betterRoleDot.ts
+++ b/src/plugins/betterRoleDot.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { Clipboard, Toasts } from "@webpack/common";
diff --git a/src/plugins/blurNsfw.ts b/src/plugins/blurNsfw.ts
index b24ded93d..dadc49be5 100644
--- a/src/plugins/blurNsfw.ts
+++ b/src/plugins/blurNsfw.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/callTimer.tsx b/src/plugins/callTimer.tsx
index f745bf625..9490eba0b 100644
--- a/src/plugins/callTimer.tsx
+++ b/src/plugins/callTimer.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/crashHandler.ts b/src/plugins/crashHandler.ts
index c70d467f7..f15fb8e9e 100644
--- a/src/plugins/crashHandler.ts
+++ b/src/plugins/crashHandler.ts
@@ -17,9 +17,9 @@
*/
import { showNotification } from "@api/Notifications";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import { closeAllModals } from "@utils/modal";
import definePlugin, { OptionType } from "@utils/types";
import { maybePromptToUpdate } from "@utils/updater";
diff --git a/src/plugins/customRPC.tsx b/src/plugins/customRPC.tsx
index ecd77e9b2..27776ef03 100644
--- a/src/plugins/customRPC.tsx
+++ b/src/plugins/customRPC.tsx
@@ -16,11 +16,11 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Link } from "@components/Link";
import { Devs } from "@utils/constants";
import { isTruthy } from "@utils/guards";
-import { useAwaiter } from "@utils/misc";
+import { useAwaiter } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types";
import { filters, findByCodeLazy, findByPropsLazy, mapMangledModuleLazy } from "@webpack";
import {
diff --git a/src/plugins/devCompanion.dev.tsx b/src/plugins/devCompanion.dev.tsx
index 161cdf9db..2fa01f257 100644
--- a/src/plugins/devCompanion.dev.tsx
+++ b/src/plugins/devCompanion.dev.tsx
@@ -17,9 +17,9 @@
*/
import { showNotification } from "@api/Notifications";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches";
import definePlugin, { OptionType } from "@utils/types";
import { filters, findAll, search } from "@webpack";
diff --git a/src/plugins/emoteCloner.tsx b/src/plugins/emoteCloner.tsx
index 61eec8865..0d651481b 100644
--- a/src/plugins/emoteCloner.tsx
+++ b/src/plugins/emoteCloner.tsx
@@ -19,7 +19,7 @@
import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
import { CheckedTextInput } from "@components/CheckedTextInput";
import { Devs } from "@utils/constants";
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins";
import { ModalContent, ModalHeader, ModalRoot, openModal } from "@utils/modal";
import definePlugin from "@utils/types";
diff --git a/src/plugins/experiments.tsx b/src/plugins/experiments.tsx
index 686b822d7..ed29aa7f4 100644
--- a/src/plugins/experiments.tsx
+++ b/src/plugins/experiments.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
diff --git a/src/plugins/fakeNitro.tsx b/src/plugins/fakeNitro.tsx
index 1fb9fc3eb..52a9d25bb 100644
--- a/src/plugins/fakeNitro.tsx
+++ b/src/plugins/fakeNitro.tsx
@@ -17,11 +17,11 @@
*/
import { addPreEditListener, addPreSendListener, removePreEditListener, removePreSendListener } from "@api/MessageEvents";
-import { definePluginSettings, Settings } from "@api/settings";
+import { definePluginSettings, Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
import { ApngBlendOp, ApngDisposeOp, getGifEncoder, importApngJs } from "@utils/dependencies";
import { getCurrentGuild } from "@utils/discord";
-import { proxyLazy } from "@utils/proxyLazy";
+import { proxyLazy } from "@utils/lazy";
import definePlugin, { OptionType } from "@utils/types";
import { findByCodeLazy, findByPropsLazy, findLazy, findStoreLazy } from "@webpack";
import { ChannelStore, FluxDispatcher, Parser, PermissionStore, UserStore } from "@webpack/common";
diff --git a/src/plugins/fakeProfileThemes.tsx b/src/plugins/fakeProfileThemes.tsx
index 8a0db1d27..70003e5ab 100644
--- a/src/plugins/fakeProfileThemes.tsx
+++ b/src/plugins/fakeProfileThemes.tsx
@@ -17,7 +17,7 @@
*/
// This plugin is a port from Alyxia's Vendetta plugin
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins";
diff --git a/src/plugins/fart.ts b/src/plugins/fart.ts
index 9404b39b0..b92a41df0 100644
--- a/src/plugins/fart.ts
+++ b/src/plugins/fart.ts
@@ -17,7 +17,7 @@
*/
import { ApplicationCommandOptionType } from "@api/Commands";
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { makeRange } from "@components/PluginSettings/components";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/ignoreActivities.tsx b/src/plugins/ignoreActivities.tsx
index f141dcef0..534b3f7f8 100644
--- a/src/plugins/ignoreActivities.tsx
+++ b/src/plugins/ignoreActivities.tsx
@@ -19,7 +19,7 @@
import * as DataStore from "@api/DataStore";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
-import { useForceUpdater } from "@utils/misc";
+import { useForceUpdater } from "@utils/react";
import definePlugin from "@utils/types";
import { findByPropsLazy, findStoreLazy } from "@webpack";
import { Tooltip } from "webpack/common";
diff --git a/src/plugins/imageZoom/index.tsx b/src/plugins/imageZoom/index.tsx
index 9007bf46b..da6ac697f 100644
--- a/src/plugins/imageZoom/index.tsx
+++ b/src/plugins/imageZoom/index.tsx
@@ -17,7 +17,7 @@
*/
import { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { disableStyle, enableStyle } from "@api/Styles";
import { makeRange } from "@components/PluginSettings/components";
import { Devs } from "@utils/constants";
diff --git a/src/plugins/index.ts b/src/plugins/index.ts
index 404f638fb..f6d577269 100644
--- a/src/plugins/index.ts
+++ b/src/plugins/index.ts
@@ -17,8 +17,8 @@
*/
import { registerCommand, unregisterCommand } from "@api/Commands";
-import { Settings } from "@api/settings";
-import Logger from "@utils/Logger";
+import { Settings } from "@api/Settings";
+import { Logger } from "@utils/Logger";
import { Patch, Plugin } from "@utils/types";
import { FluxDispatcher } from "@webpack/common";
import { FluxEvents } from "@webpack/types";
diff --git a/src/plugins/invisibleChat/index.tsx b/src/plugins/invisibleChat/index.tsx
index 0501a182d..eb92d7640 100644
--- a/src/plugins/invisibleChat/index.tsx
+++ b/src/plugins/invisibleChat/index.tsx
@@ -17,7 +17,7 @@
*/
import { addButton, removeButton } from "@api/MessagePopover";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { getStegCloak } from "@utils/dependencies";
diff --git a/src/plugins/lastfm.tsx b/src/plugins/lastfm.tsx
index c001a5977..380d1ea97 100644
--- a/src/plugins/lastfm.tsx
+++ b/src/plugins/lastfm.tsx
@@ -16,10 +16,10 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Link } from "@components/Link";
import { Devs } from "@utils/constants";
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
import { filters, findByPropsLazy, mapMangledModuleLazy } from "@webpack";
import { FluxDispatcher, Forms } from "@webpack/common";
diff --git a/src/plugins/messageLinkEmbeds.tsx b/src/plugins/messageLinkEmbeds.tsx
index 951835abc..d1fcbf357 100644
--- a/src/plugins/messageLinkEmbeds.tsx
+++ b/src/plugins/messageLinkEmbeds.tsx
@@ -17,11 +17,12 @@
*/
import { addAccessory } from "@api/MessageAccessories";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants.js";
-import { classes, LazyComponent } from "@utils/misc";
+import { classes } from "@utils/misc";
import { Queue } from "@utils/Queue";
+import { LazyComponent } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types";
import { find, findByCode, findByPropsLazy } from "@webpack";
import {
diff --git a/src/plugins/messageLogger/index.tsx b/src/plugins/messageLogger/index.tsx
index 484429fbf..2da7c2e68 100644
--- a/src/plugins/messageLogger/index.tsx
+++ b/src/plugins/messageLogger/index.tsx
@@ -19,11 +19,11 @@
import "./messageLogger.css";
import { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { disableStyle, enableStyle } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { FluxDispatcher, i18n, Menu, moment, Parser, Timestamp, UserStore } from "@webpack/common";
diff --git a/src/plugins/messageTags.ts b/src/plugins/messageTags.ts
index 02d1e529f..d65c388c3 100644
--- a/src/plugins/messageTags.ts
+++ b/src/plugins/messageTags.ts
@@ -18,7 +18,7 @@
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, registerCommand, sendBotMessage, unregisterCommand } from "@api/Commands";
import * as DataStore from "@api/DataStore";
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/moreUserTags.ts b/src/plugins/moreUserTags.ts
index 3fa0aa1bf..90662b0c8 100644
--- a/src/plugins/moreUserTags.ts
+++ b/src/plugins/moreUserTags.ts
@@ -16,9 +16,9 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
-import { proxyLazy } from "@utils/proxyLazy.js";
+import { proxyLazy } from "@utils/lazy.js";
import definePlugin, { OptionType } from "@utils/types";
import { find, findByPropsLazy } from "@webpack";
import { ChannelStore, GuildStore } from "@webpack/common";
diff --git a/src/plugins/moyai.ts b/src/plugins/moyai.ts
index b32bd9928..1a48bd67b 100644
--- a/src/plugins/moyai.ts
+++ b/src/plugins/moyai.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { makeRange } from "@components/PluginSettings/components/SettingSliderComponent";
import { Devs } from "@utils/constants";
import { sleep } from "@utils/misc";
diff --git a/src/plugins/muteNewGuild.tsx b/src/plugins/muteNewGuild.tsx
index cf15b7717..e5e618f7c 100644
--- a/src/plugins/muteNewGuild.tsx
+++ b/src/plugins/muteNewGuild.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import { ModalContent, ModalFooter, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/noBlockedMessages.ts b/src/plugins/noBlockedMessages.ts
index d91572a8b..54bb2d051 100644
--- a/src/plugins/noBlockedMessages.ts
+++ b/src/plugins/noBlockedMessages.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
diff --git a/src/plugins/noReplyMention.tsx b/src/plugins/noReplyMention.tsx
index 1351ec467..3ec8aefa8 100644
--- a/src/plugins/noReplyMention.tsx
+++ b/src/plugins/noReplyMention.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import type { Message } from "discord-types/general";
diff --git a/src/plugins/petpet.ts b/src/plugins/petpet.ts
index 472c6c9bb..9b1c2f162 100644
--- a/src/plugins/petpet.ts
+++ b/src/plugins/petpet.ts
@@ -19,7 +19,7 @@
import { ApplicationCommandInputType, ApplicationCommandOptionType, Argument, CommandContext, findOption, sendBotMessage } from "@api/Commands";
import { Devs } from "@utils/constants";
import { getGifEncoder } from "@utils/dependencies";
-import { makeLazy } from "@utils/misc";
+import { makeLazy } from "@utils/lazy";
import definePlugin from "@utils/types";
import { findByCodeLazy, findByPropsLazy } from "@webpack";
diff --git a/src/plugins/pinDms/settings.ts b/src/plugins/pinDms/settings.ts
index e8bd267a9..1e0244ed7 100644
--- a/src/plugins/pinDms/settings.ts
+++ b/src/plugins/pinDms/settings.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings, Settings, useSettings } from "@api/settings";
+import { definePluginSettings, Settings, useSettings } from "@api/Settings";
import { OptionType } from "@utils/types";
import { findStoreLazy } from "@webpack";
diff --git a/src/plugins/platformIndicators.tsx b/src/plugins/platformIndicators.tsx
index d6b42a6cb..03165bf58 100644
--- a/src/plugins/platformIndicators.tsx
+++ b/src/plugins/platformIndicators.tsx
@@ -19,7 +19,7 @@
import { addBadge, BadgePosition, ProfileBadge, removeBadge } from "@api/Badges";
import { addDecorator, removeDecorator } from "@api/MemberListDecorators";
import { addDecoration, removeDecoration } from "@api/MessageDecorations";
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/pronoundb/pronoundbUtils.ts b/src/plugins/pronoundb/pronoundbUtils.ts
index c079e36b0..6a1fb31c8 100644
--- a/src/plugins/pronoundb/pronoundbUtils.ts
+++ b/src/plugins/pronoundb/pronoundbUtils.ts
@@ -16,10 +16,10 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { VENCORD_USER_AGENT } from "@utils/constants";
import { debounce } from "@utils/debounce";
-import { useAwaiter } from "@utils/misc";
+import { useAwaiter } from "@utils/react";
import { UserStore } from "@webpack/common";
import { settings } from "./settings";
diff --git a/src/plugins/pronoundb/settings.ts b/src/plugins/pronoundb/settings.ts
index 4ccadaa14..2bd82887c 100644
--- a/src/plugins/pronoundb/settings.ts
+++ b/src/plugins/pronoundb/settings.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { OptionType } from "@utils/types";
import { PronounsFormat } from "./pronoundbUtils";
diff --git a/src/plugins/quickReply.ts b/src/plugins/quickReply.ts
index b038b6961..d855f9e44 100644
--- a/src/plugins/quickReply.ts
+++ b/src/plugins/quickReply.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings, Settings } from "@api/settings";
+import { definePluginSettings, Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
diff --git a/src/plugins/relationshipNotifier/settings.ts b/src/plugins/relationshipNotifier/settings.ts
index 1ed36ea77..91126f201 100644
--- a/src/plugins/relationshipNotifier/settings.ts
+++ b/src/plugins/relationshipNotifier/settings.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { OptionType } from "@utils/types";
export default definePluginSettings({
diff --git a/src/plugins/reviewDB/Utils/ReviewDBAPI.ts b/src/plugins/reviewDB/Utils/ReviewDBAPI.ts
index b9f48d28a..62c89f5c9 100644
--- a/src/plugins/reviewDB/Utils/ReviewDBAPI.ts
+++ b/src/plugins/reviewDB/Utils/ReviewDBAPI.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { Review } from "../entities/Review";
import { ReviewDBUser } from "../entities/User";
diff --git a/src/plugins/reviewDB/Utils/Utils.tsx b/src/plugins/reviewDB/Utils/Utils.tsx
index 7fb907b3f..d09c8d498 100644
--- a/src/plugins/reviewDB/Utils/Utils.tsx
+++ b/src/plugins/reviewDB/Utils/Utils.tsx
@@ -16,8 +16,8 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
-import Logger from "@utils/Logger";
+import { Settings } from "@api/Settings";
+import { Logger } from "@utils/Logger";
import { openModal } from "@utils/modal";
import { findByProps } from "@webpack";
import { FluxDispatcher, React, SelectedChannelStore, Toasts, UserUtils } from "@webpack/common";
diff --git a/src/plugins/reviewDB/components/MessageButton.tsx b/src/plugins/reviewDB/components/MessageButton.tsx
index 2e4bba749..3b8308ab1 100644
--- a/src/plugins/reviewDB/components/MessageButton.tsx
+++ b/src/plugins/reviewDB/components/MessageButton.tsx
@@ -16,11 +16,12 @@
* along with this program. If not, see .
*/
-import { classes, LazyComponent } from "@utils/misc";
+import { classes } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
import { findByProps } from "@webpack";
export default LazyComponent(() => {
- const { button, dangerous } = findByProps("button", "wrapper", "disabled","separator");
+ const { button, dangerous } = findByProps("button", "wrapper", "disabled", "separator");
return function MessageButton(props) {
return props.type === "delete"
diff --git a/src/plugins/reviewDB/components/ReviewComponent.tsx b/src/plugins/reviewDB/components/ReviewComponent.tsx
index 76497d19a..04973d75d 100644
--- a/src/plugins/reviewDB/components/ReviewComponent.tsx
+++ b/src/plugins/reviewDB/components/ReviewComponent.tsx
@@ -16,8 +16,9 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
-import { classes, LazyComponent } from "@utils/misc";
+import { Settings } from "@api/Settings";
+import { classes } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
import { filters, findBulk } from "@webpack";
import { Alerts, moment, Timestamp, UserStore } from "@webpack/common";
diff --git a/src/plugins/reviewDB/components/ReviewsView.tsx b/src/plugins/reviewDB/components/ReviewsView.tsx
index 777a9c171..f4bd2481c 100644
--- a/src/plugins/reviewDB/components/ReviewsView.tsx
+++ b/src/plugins/reviewDB/components/ReviewsView.tsx
@@ -16,8 +16,9 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
-import { classes, useAwaiter } from "@utils/misc";
+import { Settings } from "@api/Settings";
+import { classes } from "@utils/misc";
+import { useAwaiter } from "@utils/react";
import { findLazy } from "@webpack";
import { Forms, React, Text, UserStore } from "@webpack/common";
import type { KeyboardEvent } from "react";
diff --git a/src/plugins/reviewDB/index.tsx b/src/plugins/reviewDB/index.tsx
index d8fc1cd23..0495c77f2 100644
--- a/src/plugins/reviewDB/index.tsx
+++ b/src/plugins/reviewDB/index.tsx
@@ -18,7 +18,7 @@
import "./style.css";
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/roleColorEverywhere.tsx b/src/plugins/roleColorEverywhere.tsx
index 88a6cc246..8b256f40c 100644
--- a/src/plugins/roleColorEverywhere.tsx
+++ b/src/plugins/roleColorEverywhere.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { ChannelStore, GuildMemberStore, GuildStore } from "@webpack/common";
diff --git a/src/plugins/searchReply.tsx b/src/plugins/searchReply.tsx
index cb09f5b69..fe6348bf1 100644
--- a/src/plugins/searchReply.tsx
+++ b/src/plugins/searchReply.tsx
@@ -18,7 +18,7 @@
import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
import { Devs } from "@utils/constants";
-import { LazyComponent } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
import definePlugin from "@utils/types";
import { findByCode, findByCodeLazy } from "@webpack";
import { ChannelStore, i18n, Menu, SelectedChannelStore } from "@webpack/common";
diff --git a/src/plugins/serverListIndicators.tsx b/src/plugins/serverListIndicators.tsx
index ed168b5f1..efb967a62 100644
--- a/src/plugins/serverListIndicators.tsx
+++ b/src/plugins/serverListIndicators.tsx
@@ -17,10 +17,10 @@
*/
import { addServerListElement, removeServerListElement, ServerListRenderPosition } from "@api/ServerList";
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
-import { useForceUpdater } from "@utils/misc";
+import { useForceUpdater } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types";
import { GuildStore, PresenceStore, RelationshipStore } from "@webpack/common";
diff --git a/src/plugins/settings.tsx b/src/plugins/settings.tsx
index 6fd424c4a..c1dd315c8 100644
--- a/src/plugins/settings.tsx
+++ b/src/plugins/settings.tsx
@@ -17,11 +17,11 @@
*/
import { addContextMenuPatch } from "@api/ContextMenu";
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import PatchHelper from "@components/PatchHelper";
import { Devs } from "@utils/constants";
-import Logger from "@utils/Logger";
-import { LazyComponent } from "@utils/misc";
+import { Logger } from "@utils/Logger";
+import { LazyComponent } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types";
import { SettingsRouter } from "@webpack/common";
diff --git a/src/plugins/shikiCodeblocks/components/Highlighter.tsx b/src/plugins/shikiCodeblocks/components/Highlighter.tsx
index badb3c8f6..dd1401939 100644
--- a/src/plugins/shikiCodeblocks/components/Highlighter.tsx
+++ b/src/plugins/shikiCodeblocks/components/Highlighter.tsx
@@ -17,8 +17,7 @@
*/
import ErrorBoundary from "@components/ErrorBoundary";
-import { useAwaiter } from "@utils/misc";
-import { useIntersection } from "@utils/react";
+import { useAwaiter, useIntersection } from "@utils/react";
import { hljs, React } from "@webpack/common";
import { resolveLang } from "../api/languages";
diff --git a/src/plugins/shikiCodeblocks/settings.ts b/src/plugins/shikiCodeblocks/settings.ts
index ff5afc2e7..f9fd3cc0f 100644
--- a/src/plugins/shikiCodeblocks/settings.ts
+++ b/src/plugins/shikiCodeblocks/settings.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { disableStyle, enableStyle } from "@api/Styles";
import { parseUrl } from "@utils/misc";
import { wordsFromPascal, wordsToTitle } from "@utils/text";
diff --git a/src/plugins/showConnections/index.tsx b/src/plugins/showConnections/index.tsx
index 3c7c94922..e2afc5b9a 100644
--- a/src/plugins/showConnections/index.tsx
+++ b/src/plugins/showConnections/index.tsx
@@ -18,10 +18,11 @@
import "./styles.css";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
-import { copyWithToast, LazyComponent } from "@utils/misc";
+import { copyWithToast } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types";
import { findByCode, findByCodeLazy, findByPropsLazy, findStoreLazy } from "@webpack";
import { Text, Tooltip } from "@webpack/common";
diff --git a/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx b/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx
index 932491b21..dc670bf0d 100644
--- a/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx
+++ b/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx
@@ -17,7 +17,7 @@
*/
import ErrorBoundary from "@components/ErrorBoundary";
-import { LazyComponent } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
import { formatDuration } from "@utils/text";
import { find, findByPropsLazy, findStoreLazy } from "@webpack";
import { FluxDispatcher, GuildMemberStore, GuildStore, moment, Parser, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip } from "@webpack/common";
diff --git a/src/plugins/showHiddenChannels/index.tsx b/src/plugins/showHiddenChannels/index.tsx
index 272ff7aae..5bcf72ffa 100644
--- a/src/plugins/showHiddenChannels/index.tsx
+++ b/src/plugins/showHiddenChannels/index.tsx
@@ -18,7 +18,7 @@
import "./style.css";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { canonicalizeMatch } from "@utils/patches";
diff --git a/src/plugins/showMeYourName/index.tsx b/src/plugins/showMeYourName/index.tsx
index 7b7b7e298..ee43331fe 100644
--- a/src/plugins/showMeYourName/index.tsx
+++ b/src/plugins/showMeYourName/index.tsx
@@ -18,13 +18,13 @@
import "./styles.css";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { Message } from "discord-types/general";
interface UsernameProps {
- author: { nick: string };
+ author: { nick: string; };
message: Message;
withMentionPrefix?: boolean;
isRepliedMessage: boolean;
diff --git a/src/plugins/silentMessageToggle.tsx b/src/plugins/silentMessageToggle.tsx
index 5e42444a1..67adec7ee 100644
--- a/src/plugins/silentMessageToggle.tsx
+++ b/src/plugins/silentMessageToggle.tsx
@@ -17,7 +17,7 @@
*/
import { addPreSendListener, removePreSendListener, SendListener } from "@api/MessageEvents";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/silentTyping.tsx b/src/plugins/silentTyping.tsx
index 28b651d39..20ebe2734 100644
--- a/src/plugins/silentTyping.tsx
+++ b/src/plugins/silentTyping.tsx
@@ -17,7 +17,7 @@
*/
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/spotifyControls/SpotifyStore.ts b/src/plugins/spotifyControls/SpotifyStore.ts
index 2ceb30ca2..c7132492e 100644
--- a/src/plugins/spotifyControls/SpotifyStore.ts
+++ b/src/plugins/spotifyControls/SpotifyStore.ts
@@ -16,8 +16,8 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
-import { proxyLazy } from "@utils/proxyLazy";
+import { Settings } from "@api/Settings";
+import { proxyLazy } from "@utils/lazy";
import { findByPropsLazy } from "@webpack";
import { Flux, FluxDispatcher } from "@webpack/common";
diff --git a/src/plugins/spotifyControls/index.tsx b/src/plugins/spotifyControls/index.tsx
index 280efce83..fa1e8960c 100644
--- a/src/plugins/spotifyControls/index.tsx
+++ b/src/plugins/spotifyControls/index.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { disableStyle, enableStyle } from "@api/Styles";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/spotifyCrack.ts b/src/plugins/spotifyCrack.ts
index c4033271d..f02df72db 100644
--- a/src/plugins/spotifyCrack.ts
+++ b/src/plugins/spotifyCrack.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/startupTimings/index.tsx b/src/plugins/startupTimings/index.tsx
index 5d66f5ffc..acb11c98d 100644
--- a/src/plugins/startupTimings/index.tsx
+++ b/src/plugins/startupTimings/index.tsx
@@ -18,7 +18,7 @@
import { Devs } from "@utils/constants";
-import { LazyComponent } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
import definePlugin from "@utils/types";
export default definePlugin({
diff --git a/src/plugins/supportHelper.tsx b/src/plugins/supportHelper.tsx
index bcb74b2d1..db38b375e 100644
--- a/src/plugins/supportHelper.tsx
+++ b/src/plugins/supportHelper.tsx
@@ -18,7 +18,7 @@
import { DataStore } from "@api/index";
import { Devs, SUPPORT_CHANNEL_ID } from "@utils/constants";
-import { makeCodeblock } from "@utils/misc";
+import { makeCodeblock } from "@utils/text";
import definePlugin from "@utils/types";
import { isOutdated } from "@utils/updater";
import { Alerts, Forms, UserStore } from "@webpack/common";
diff --git a/src/plugins/textReplace.tsx b/src/plugins/textReplace.tsx
index 21aa75333..f41afc5af 100644
--- a/src/plugins/textReplace.tsx
+++ b/src/plugins/textReplace.tsx
@@ -18,11 +18,11 @@
import { DataStore } from "@api/index";
import { addPreSendListener, removePreSendListener } from "@api/MessageEvents";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Flex } from "@components/Flex";
import { Devs } from "@utils/constants";
-import Logger from "@utils/Logger";
-import { useForceUpdater } from "@utils/misc";
+import { Logger } from "@utils/Logger";
+import { useForceUpdater } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types";
import { Button, Forms, React, TextInput, useState } from "@webpack/common";
diff --git a/src/plugins/typingIndicator.tsx b/src/plugins/typingIndicator.tsx
index 8f98d5b34..bad95d204 100644
--- a/src/plugins/typingIndicator.tsx
+++ b/src/plugins/typingIndicator.tsx
@@ -16,10 +16,10 @@
* along with this program. If not, see .
*/
-import { definePluginSettings, Settings } from "@api/settings";
+import { definePluginSettings, Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
-import { LazyComponent } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types";
import { find, findLazy, findStoreLazy } from "@webpack";
import { ChannelStore, GuildMemberStore, RelationshipStore, Tooltip, UserStore, useStateFromStores } from "@webpack/common";
diff --git a/src/plugins/typingTweaks.tsx b/src/plugins/typingTweaks.tsx
index 22eafdbae..d9fe7eca6 100644
--- a/src/plugins/typingTweaks.tsx
+++ b/src/plugins/typingTweaks.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/userVoiceShow/index.tsx b/src/plugins/userVoiceShow/index.tsx
index 3379672ce..3b6609b0e 100644
--- a/src/plugins/userVoiceShow/index.tsx
+++ b/src/plugins/userVoiceShow/index.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/usrbg/index.tsx b/src/plugins/usrbg/index.tsx
index 9c72676a1..cdb7260b5 100644
--- a/src/plugins/usrbg/index.tsx
+++ b/src/plugins/usrbg/index.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { enableStyle } from "@api/Styles";
import { Link } from "@components/Link";
import { Devs } from "@utils/constants";
diff --git a/src/plugins/vcNarrator.tsx b/src/plugins/vcNarrator.tsx
index a318e8916..575dcbc4c 100644
--- a/src/plugins/vcNarrator.tsx
+++ b/src/plugins/vcNarrator.tsx
@@ -16,10 +16,10 @@
* along with this program. If not, see .
*/
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { ErrorCard } from "@components/ErrorCard";
import { Devs } from "@utils/constants";
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins";
import { wordsToTitle } from "@utils/text";
import definePlugin, { OptionType, PluginOptionsItem } from "@utils/types";
diff --git a/src/plugins/vencordToolbox/index.tsx b/src/plugins/vencordToolbox/index.tsx
index c2bfe6c8b..ab05d7b34 100644
--- a/src/plugins/vencordToolbox/index.tsx
+++ b/src/plugins/vencordToolbox/index.tsx
@@ -21,7 +21,7 @@ import "./index.css";
import { openNotificationLogModal } from "@api/Notifications/notificationLog";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
-import { LazyComponent } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
import definePlugin from "@utils/types";
import { findByCode } from "@webpack";
import { Menu, Popout, useState } from "@webpack/common";
diff --git a/src/plugins/viewIcons.tsx b/src/plugins/viewIcons.tsx
index dea5bf8a0..3463895e0 100644
--- a/src/plugins/viewIcons.tsx
+++ b/src/plugins/viewIcons.tsx
@@ -17,10 +17,10 @@
*/
import { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
-import { LazyComponent } from "@utils/misc";
import { ModalRoot, ModalSize, openModal } from "@utils/modal";
+import { LazyComponent } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types";
import { find, findByCode, findByPropsLazy } from "@webpack";
import { GuildMemberStore, Menu } from "@webpack/common";
diff --git a/src/plugins/volumeBooster.discordDesktop.ts b/src/plugins/volumeBooster.discordDesktop.ts
index ac112155d..4aca79fc7 100644
--- a/src/plugins/volumeBooster.discordDesktop.ts
+++ b/src/plugins/volumeBooster.discordDesktop.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { makeRange } from "@components/PluginSettings/components";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
diff --git a/src/plugins/webContextMenus.web.ts b/src/plugins/webContextMenus.web.ts
index 4ded483c7..bab82b4a0 100644
--- a/src/plugins/webContextMenus.web.ts
+++ b/src/plugins/webContextMenus.web.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { saveFile } from "@utils/web";
diff --git a/src/plugins/welcomeStickerPicker.tsx b/src/plugins/welcomeStickerPicker.tsx
index 40af7e2a0..7aaded2c3 100644
--- a/src/plugins/welcomeStickerPicker.tsx
+++ b/src/plugins/welcomeStickerPicker.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
diff --git a/src/plugins/whoReacted.tsx b/src/plugins/whoReacted.tsx
index 6ceb301ca..0bdb5c27e 100644
--- a/src/plugins/whoReacted.tsx
+++ b/src/plugins/whoReacted.tsx
@@ -18,8 +18,9 @@
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
-import { LazyComponent, sleep, useForceUpdater } from "@utils/misc";
+import { sleep } from "@utils/misc";
import { Queue } from "@utils/Queue";
+import { LazyComponent, useForceUpdater } from "@utils/react";
import definePlugin from "@utils/types";
import { findByCode, findByPropsLazy } from "@webpack";
import { ChannelStore, FluxDispatcher, React, RestAPI, Tooltip } from "@webpack/common";
diff --git a/src/utils/Logger.ts b/src/utils/Logger.ts
index 88ebb43b1..1ae4762d7 100644
--- a/src/utils/Logger.ts
+++ b/src/utils/Logger.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-export default class Logger {
+export class Logger {
/**
* Returns the console format args for a title with the specified background colour and black text
* @param color Background colour
diff --git a/src/utils/cloud.tsx b/src/utils/cloud.tsx
index b31091f08..5f853bd30 100644
--- a/src/utils/cloud.tsx
+++ b/src/utils/cloud.tsx
@@ -18,11 +18,11 @@
import * as DataStore from "@api/DataStore";
import { showNotification } from "@api/Notifications";
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import { findByProps } from "@webpack";
import { UserStore } from "@webpack/common";
-import Logger from "./Logger";
+import { Logger } from "./Logger";
import { openModal } from "./modal";
export const cloudLogger = new Logger("Cloud", "#39b7e0");
diff --git a/src/utils/constants.ts b/src/utils/constants.ts
index 69eb60441..a10a0a58b 100644
--- a/src/utils/constants.ts
+++ b/src/utils/constants.ts
@@ -19,6 +19,11 @@
import gitHash from "~git-hash";
import gitRemote from "~git-remote";
+export {
+ gitHash,
+ gitRemote
+};
+
export const WEBPACK_CHUNK = "webpackChunkdiscord_app";
export const REACT_GLOBAL = "Vencord.Webpack.Common.React";
export const VENCORD_USER_AGENT = `Vencord/${gitHash}${gitRemote ? ` (https://github.com/${gitRemote})` : ""}`;
diff --git a/src/utils/dependencies.ts b/src/utils/dependencies.ts
index a09a87b2f..67bf5025f 100644
--- a/src/utils/dependencies.ts
+++ b/src/utils/dependencies.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { makeLazy } from "./misc";
+import { makeLazy } from "./lazy";
/*
Add dynamically loaded dependencies for plugins here.
diff --git a/src/utils/index.ts b/src/utils/index.ts
index 6723a7041..fd15f3d3a 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -17,15 +17,18 @@
*/
export * from "./ChangeList";
-export * as Constants from "./constants";
+export * from "./constants";
export * from "./debounce";
-export * as Discord from "./discord";
-export { default as Logger } from "./Logger";
+export * from "./discord";
+export * from "./guards";
+export * from "./lazy";
+export * from "./localStorage";
+export * from "./Logger";
export * from "./margins";
export * from "./misc";
-export * as Modals from "./modal";
+export * from "./modal";
export * from "./onceDefined";
export * from "./onlyOnce";
-export * from "./proxyLazy";
+export * from "./patches";
export * from "./Queue";
export * from "./text";
diff --git a/src/utils/proxyLazy.ts b/src/utils/lazy.ts
similarity index 91%
rename from src/utils/proxyLazy.ts
rename to src/utils/lazy.ts
index b1fca6e77..1e1dd5f58 100644
--- a/src/utils/proxyLazy.ts
+++ b/src/utils/lazy.ts
@@ -16,6 +16,11 @@
* along with this program. If not, see .
*/
+export function makeLazy(factory: () => T): () => T {
+ let cache: T;
+ return () => cache ?? (cache = factory());
+}
+
// Proxies demand that these properties be unmodified, so proxyLazy
// will always return the function default for them.
const unconfigurable = ["arguments", "caller", "prototype"];
@@ -73,7 +78,7 @@ handler.getOwnPropertyDescriptor = (target, p) => {
* @example const mod = proxyLazy(() => findByProps("blah")); console.log(mod.blah);
*/
export function proxyLazy(factory: () => T): T {
- const proxyDummy: { (): void; [CACHED_KEY]?: T; [GET_KEY](): T; } = Object.assign(function () { }, {
+ const proxyDummy: { (): void;[CACHED_KEY]?: T;[GET_KEY](): T; } = Object.assign(function () { }, {
[CACHED_KEY]: void 0,
[GET_KEY]: () => proxyDummy[CACHED_KEY] ??= factory(),
});
diff --git a/src/utils/misc.tsx b/src/utils/misc.tsx
index b6a6423fb..59475cbd7 100644
--- a/src/utils/misc.tsx
+++ b/src/utils/misc.tsx
@@ -16,79 +16,7 @@
* along with this program. If not, see .
*/
-import { Clipboard, React, Toasts, useEffect, useState } from "@webpack/common";
-
-/**
- * Makes a lazy function. On first call, the value is computed.
- * On subsequent calls, the same computed value will be returned
- * @param factory Factory function
- */
-export function makeLazy(factory: () => T): () => T {
- let cache: T;
- return () => cache ?? (cache = factory());
-}
-
-type AwaiterRes = [T, any, boolean];
-interface AwaiterOpts {
- fallbackValue: T,
- deps?: unknown[],
- onError?(e: any): void,
-}
-/**
- * Await a promise
- * @param factory Factory
- * @param fallbackValue The fallback value that will be used until the promise resolved
- * @returns [value, error, isPending]
- */
-export function useAwaiter(factory: () => Promise): AwaiterRes;
-export function useAwaiter(factory: () => Promise, providedOpts: AwaiterOpts): AwaiterRes;
-export function useAwaiter(factory: () => Promise, providedOpts?: AwaiterOpts): AwaiterRes {
- const opts: Required> = Object.assign({
- fallbackValue: null,
- deps: [],
- onError: null,
- }, providedOpts);
- const [state, setState] = useState({
- value: opts.fallbackValue,
- error: null,
- pending: true
- });
-
- useEffect(() => {
- let isAlive = true;
- if (!state.pending) setState({ ...state, pending: true });
-
- factory()
- .then(value => isAlive && setState({ value, error: null, pending: false }))
- .catch(error => isAlive && (setState({ value: null, error, pending: false }), opts.onError?.(error)));
-
- return () => void (isAlive = false);
- }, opts.deps);
-
- return [state.value, state.error, state.pending];
-}
-
-/**
- * Returns a function that can be used to force rerender react components
- */
-export function useForceUpdater() {
- const [, set] = useState(0);
- return () => set(s => s + 1);
-}
-
-/**
- * A lazy component. The factory method is called on first render. For example useful
- * for const Component = LazyComponent(() => findByDisplayName("...").default)
- * @param factory Function returning a Component
- * @returns Result of factory function
- */
-export function LazyComponent(factory: () => React.ComponentType) {
- const get = makeLazy(factory);
- return (props: T & JSX.IntrinsicAttributes) => {
- const Component = get();
- return ;
- };
-}
+import { Clipboard, Toasts } from "@webpack/common";
/**
* Recursively merges defaults into an object and returns the same object
@@ -109,34 +37,6 @@ export function mergeDefaults(obj: T, defaults: T): T {
return obj;
}
-
-/**
- * Join an array of strings in a human readable way (1, 2 and 3)
- * @param elements Elements
- */
-export function humanFriendlyJoin(elements: string[]): string;
-/**
- * Join an array of strings in a human readable way (1, 2 and 3)
- * @param elements Elements
- * @param mapper Function that converts elements to a string
- */
-export function humanFriendlyJoin(elements: T[], mapper: (e: T) => string): string;
-export function humanFriendlyJoin(elements: any[], mapper: (e: any) => string = s => s): string {
- const { length } = elements;
- if (length === 0) return "";
- if (length === 1) return mapper(elements[0]);
-
- let s = "";
-
- for (let i = 0; i < length; i++) {
- s += mapper(elements[i]);
- if (length - i > 2) s += ", ";
- else if (length - i > 1) s += " and ";
- }
-
- return s;
-}
-
/**
* Calls .join(" ") on the arguments
* classes("one", "two") => "one two"
@@ -152,14 +52,6 @@ export function sleep(ms: number): Promise {
return new Promise(r => setTimeout(r, ms));
}
-/**
- * Wrap the text in ``` with an optional language
- */
-export function makeCodeblock(text: string, language?: string) {
- const chars = "```";
- return `${chars}${language || ""}\n${text.replaceAll("```", "\\`\\`\\`")}\n${chars}`;
-}
-
export function copyWithToast(text: string, toastMessage = "Copied to clipboard!") {
if (Clipboard.SUPPORTS_COPY) {
Clipboard.copy(text);
diff --git a/src/utils/modal.tsx b/src/utils/modal.tsx
index 35aaaf889..173862370 100644
--- a/src/utils/modal.tsx
+++ b/src/utils/modal.tsx
@@ -19,7 +19,7 @@
import { filters, mapMangledModuleLazy } from "@webpack";
import type { ComponentType, PropsWithChildren, ReactNode, Ref } from "react";
-import { LazyComponent } from "./misc";
+import { LazyComponent } from "./react";
export enum ModalSize {
SMALL = "small",
diff --git a/src/utils/quickCss.ts b/src/utils/quickCss.ts
index 1b3f78d34..fe35a3c28 100644
--- a/src/utils/quickCss.ts
+++ b/src/utils/quickCss.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { addSettingsListener, Settings } from "@api/settings";
+import { addSettingsListener, Settings } from "@api/Settings";
let style: HTMLStyleElement;
diff --git a/src/utils/react.ts b/src/utils/react.ts
deleted file mode 100644
index e5e1f677d..000000000
--- a/src/utils/react.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Vencord, a modification for Discord's desktop app
- * Copyright (c) 2022 Vendicated and contributors
- *
- * 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 { React, useState } from "@webpack/common";
-
-import { checkIntersecting } from "./misc";
-
-/**
- * Check if an element is on screen
- * @param intersectOnly If `true`, will only update the state when the element comes into view
- * @returns [refCallback, isIntersecting]
- */
-export const useIntersection = (intersectOnly = false): [
- refCallback: React.RefCallback,
- isIntersecting: boolean,
-] => {
- const observerRef = React.useRef(null);
- const [isIntersecting, setIntersecting] = useState(false);
-
- const refCallback = (element: Element | null) => {
- observerRef.current?.disconnect();
- observerRef.current = null;
-
- if (!element) return;
-
- if (checkIntersecting(element)) {
- setIntersecting(true);
- if (intersectOnly) return;
- }
-
- observerRef.current = new IntersectionObserver(entries => {
- for (const entry of entries) {
- if (entry.target !== element) continue;
- if (entry.isIntersecting && intersectOnly) {
- setIntersecting(true);
- observerRef.current?.disconnect();
- observerRef.current = null;
- } else {
- setIntersecting(entry.isIntersecting);
- }
- }
- });
- observerRef.current.observe(element);
- };
-
- return [refCallback, isIntersecting];
-};
diff --git a/src/utils/react.tsx b/src/utils/react.tsx
new file mode 100644
index 000000000..69c1df252
--- /dev/null
+++ b/src/utils/react.tsx
@@ -0,0 +1,128 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 Vendicated and contributors
+ *
+ * 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 { React, useEffect, useReducer, useState } from "@webpack/common";
+
+import { makeLazy } from "./lazy";
+import { checkIntersecting } from "./misc";
+
+/**
+ * Check if an element is on screen
+ * @param intersectOnly If `true`, will only update the state when the element comes into view
+ * @returns [refCallback, isIntersecting]
+ */
+export const useIntersection = (intersectOnly = false): [
+ refCallback: React.RefCallback,
+ isIntersecting: boolean,
+] => {
+ const observerRef = React.useRef(null);
+ const [isIntersecting, setIntersecting] = useState(false);
+
+ const refCallback = (element: Element | null) => {
+ observerRef.current?.disconnect();
+ observerRef.current = null;
+
+ if (!element) return;
+
+ if (checkIntersecting(element)) {
+ setIntersecting(true);
+ if (intersectOnly) return;
+ }
+
+ observerRef.current = new IntersectionObserver(entries => {
+ for (const entry of entries) {
+ if (entry.target !== element) continue;
+ if (entry.isIntersecting && intersectOnly) {
+ setIntersecting(true);
+ observerRef.current?.disconnect();
+ observerRef.current = null;
+ } else {
+ setIntersecting(entry.isIntersecting);
+ }
+ }
+ });
+ observerRef.current.observe(element);
+ };
+
+ return [refCallback, isIntersecting];
+};
+
+type AwaiterRes = [T, any, boolean];
+interface AwaiterOpts {
+ fallbackValue: T;
+ deps?: unknown[];
+ onError?(e: any): void;
+}
+/**
+ * Await a promise
+ * @param factory Factory
+ * @param fallbackValue The fallback value that will be used until the promise resolved
+ * @returns [value, error, isPending]
+ */
+
+export function useAwaiter(factory: () => Promise): AwaiterRes;
+export function useAwaiter(factory: () => Promise, providedOpts: AwaiterOpts): AwaiterRes;
+export function useAwaiter(factory: () => Promise, providedOpts?: AwaiterOpts): AwaiterRes {
+ const opts: Required> = Object.assign({
+ fallbackValue: null,
+ deps: [],
+ onError: null,
+ }, providedOpts);
+ const [state, setState] = useState({
+ value: opts.fallbackValue,
+ error: null,
+ pending: true
+ });
+
+ useEffect(() => {
+ let isAlive = true;
+ if (!state.pending) setState({ ...state, pending: true });
+
+ factory()
+ .then(value => isAlive && setState({ value, error: null, pending: false }))
+ .catch(error => isAlive && (setState({ value: null, error, pending: false }), opts.onError?.(error)));
+
+ return () => void (isAlive = false);
+ }, opts.deps);
+
+ return [state.value, state.error, state.pending];
+}
+/**
+ * Returns a function that can be used to force rerender react components
+ */
+
+export function useForceUpdater(): () => void;
+export function useForceUpdater(withDep: true): [unknown, () => void];
+export function useForceUpdater(withDep?: true) {
+ const r = useReducer(x => x + 1, 0);
+ return withDep ? r : r[1];
+}
+/**
+ * A lazy component. The factory method is called on first render. For example useful
+ * for const Component = LazyComponent(() => findByDisplayName("...").default)
+ * @param factory Function returning a Component
+ * @returns Result of factory function
+ */
+
+export function LazyComponent(factory: () => React.ComponentType) {
+ const get = makeLazy(factory);
+ return (props: T) => {
+ const Component = get();
+ return ;
+ };
+}
diff --git a/src/utils/settingsSync.ts b/src/utils/settingsSync.ts
index 3ec2d4328..ef04391cd 100644
--- a/src/utils/settingsSync.ts
+++ b/src/utils/settingsSync.ts
@@ -17,12 +17,12 @@
*/
import { showNotification } from "@api/Notifications";
-import { PlainSettings, Settings } from "@api/settings";
+import { PlainSettings, Settings } from "@api/Settings";
import { Toasts } from "@webpack/common";
import { deflateSync, inflateSync } from "fflate";
import { getCloudAuth, getCloudUrl } from "./cloud";
-import Logger from "./Logger";
+import { Logger } from "./Logger";
import { saveFile } from "./web";
export async function importSettings(data: string) {
diff --git a/src/utils/text.ts b/src/utils/text.ts
index 115b3e2ac..63f600742 100644
--- a/src/utils/text.ts
+++ b/src/utils/text.ts
@@ -92,3 +92,42 @@ export function formatDuration(time: number, unit: Units, short: boolean = false
return res.length ? res : `0 ${getUnitStr(unit, false, short)}`;
}
+
+/**
+ * Join an array of strings in a human readable way (1, 2 and 3)
+ * @param elements Elements
+ */
+export function humanFriendlyJoin(elements: string[]): string;
+/**
+ * Join an array of strings in a human readable way (1, 2 and 3)
+ * @param elements Elements
+ * @param mapper Function that converts elements to a string
+ */
+export function humanFriendlyJoin(elements: T[], mapper: (e: T) => string): string;
+export function humanFriendlyJoin(elements: any[], mapper: (e: any) => string = s => s): string {
+ const { length } = elements;
+ if (length === 0)
+ return "";
+ if (length === 1)
+ return mapper(elements[0]);
+
+ let s = "";
+
+ for (let i = 0; i < length; i++) {
+ s += mapper(elements[i]);
+ if (length - i > 2)
+ s += ", ";
+ else if (length - i > 1)
+ s += " and ";
+ }
+
+ return s;
+}
+
+/**
+ * Wrap the text in ``` with an optional language
+ */
+export function makeCodeblock(text: string, language?: string) {
+ const chars = "```";
+ return `${chars}${language || ""}\n${text.replaceAll("```", "\\`\\`\\`")}\n${chars}`;
+}
diff --git a/src/utils/updater.ts b/src/utils/updater.ts
index ce99aa4fd..2e2bfe1a1 100644
--- a/src/utils/updater.ts
+++ b/src/utils/updater.ts
@@ -18,7 +18,7 @@
import gitHash from "~git-hash";
-import Logger from "./Logger";
+import { Logger } from "./Logger";
import { relaunch } from "./native";
import { IpcRes } from "./types";
diff --git a/src/webpack/common/internal.tsx b/src/webpack/common/internal.tsx
index e2f42d8c3..66c52de00 100644
--- a/src/webpack/common/internal.tsx
+++ b/src/webpack/common/internal.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { LazyComponent } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
// eslint-disable-next-line path-alias/no-relative
import { FilterFn, filters, waitFor } from "../webpack";
diff --git a/src/webpack/patchWebpack.ts b/src/webpack/patchWebpack.ts
index 697ce9496..f33ddc32f 100644
--- a/src/webpack/patchWebpack.ts
+++ b/src/webpack/patchWebpack.ts
@@ -17,7 +17,7 @@
*/
import { WEBPACK_CHUNK } from "@utils/constants";
-import Logger from "@utils/Logger";
+import { Logger } from "@utils/Logger";
import { canonicalizeReplacement } from "@utils/patches";
import { PatchReplacement } from "@utils/types";
diff --git a/src/webpack/webpack.ts b/src/webpack/webpack.ts
index ffa2daadd..8a5fc4061 100644
--- a/src/webpack/webpack.ts
+++ b/src/webpack/webpack.ts
@@ -16,8 +16,8 @@
* along with this program. If not, see .
*/
-import Logger from "@utils/Logger";
-import { proxyLazy } from "@utils/proxyLazy";
+import { proxyLazy } from "@utils/lazy";
+import { Logger } from "@utils/Logger";
import type { WebpackInstance } from "discord-types/other";
import { traceFunction } from "../debug/Tracer";