Immediate finds

This commit is contained in:
Nuckyz 2024-05-02 23:18:12 -03:00
parent 86b53b24a6
commit 75fa0ff708
No known key found for this signature in database
GPG key ID: 440BF8296E1C4AD9
107 changed files with 1400 additions and 1229 deletions

View file

@ -400,7 +400,7 @@ async function runtime(token: string) {
}
Vencord.Webpack.waitFor(
"loginToken",
Vencord.Webpack.filters.byProps("loginToken"),
m => {
console.log("[PUP_DEBUG]", "Logging in with token...");
m.loginToken(token);
@ -471,39 +471,62 @@ async function runtime(token: string) {
}
}
for (const [searchType, args] of Vencord.Webpack.lazyWebpackSearchHistory) {
let method = searchType;
for (const [searchType, args] of [...Vencord.Webpack.webpackSearchHistory]) {
let method = searchType as string;
if (searchType === "findComponent") method = "find";
if (searchType === "findExportedComponent") method = "findByProps";
if (searchType === "waitFor" || searchType === "waitForComponent") {
if (typeof args[0] === "string") method = "findByProps";
else method = "find";
}
if (searchType === "waitForStore") method = "findStore";
if (searchType === "waitFor") method = "cacheFind";
try {
let result: any;
if (method === "proxyLazyWebpack" || method === "LazyComponentWebpack") {
if (method === "webpackDependantLazy" || method === "webpackDependantLazyComponent") {
const [factory] = args;
result = factory();
if (result != null && "$$vencordGetter" in result) result = result.$$vencordGetter();
} else if (method === "extractAndLoadChunks") {
const [code, matcher] = args;
const module = Vencord.Webpack.findModuleFactory(...code);
if (module) result = module.toString().match(canonicalizeMatch(matcher));
if (module) result = module.toString().match(Vencord.Util.canonicalizeMatch(matcher));
} else {
// @ts-ignore
result = Vencord.Webpack[method](...args);
// If the result is our Proxy or ComponentWrapper, this means the search failed
if (result != null && result[Vencord.Util.proxyInnerGet] != null) result = undefined;
if (result != null && "$$vencordGetter" in result) result = undefined;
}
if (result == null || ("$$vencordInternal" in result && result.$$vencordInternal() == null)) throw "a rock at ben shapiro";
if (result == null) throw "find failed";
} catch (e) {
let logMessage = searchType;
if (method === "find" || method === "proxyLazyWebpack" || method === "LazyComponentWebpack") logMessage += `(${args[0].toString().slice(0, 147)}...)`;
else if (method === "extractAndLoadChunks") logMessage += `([${args[0].map(arg => `"${arg}"`).join(", ")}], ${args[1].toString()})`;
else logMessage += `(${args.map(arg => `"${arg}"`).join(", ")})`;
let filterName = "";
let parsedArgs = args;
if ("$$vencordProps" in args[0]) {
if (
searchType === "find" ||
searchType === "findComponent" ||
searchType === "waitFor"
) {
filterName = args[0].$$vencordProps[0];
}
parsedArgs = args[0].$$vencordProps.slice(1);
}
if (
parsedArgs === args && searchType === "waitFor" ||
searchType === "find" ||
searchType === "findComponent" ||
searchType === "webpackDependantLazy" ||
searchType === "webpackDependantLazyComponent"
) {
logMessage += `(${parsedArgs[0].toString().slice(0, 147)}...)`;
} else if (searchType === "extractAndLoadChunks") {
logMessage += `([${parsedArgs[0].map((arg: any) => `"${arg}"`).join(", ")}], ${parsedArgs[1].toString()})`;
} else {
logMessage += `(${filterName.length ? `${filterName}(` : ""}${parsedArgs.map(arg => `"${arg}"`).join(", ")})${filterName.length ? ")" : ""}`;
}
console.log("[PUP_WEBPACK_FIND_FAIL]", logMessage);
}

View file

@ -8,13 +8,12 @@ import "./ChatButton.css";
import ErrorBoundary from "@components/ErrorBoundary";
import { Logger } from "@utils/Logger";
import { waitFor } from "@webpack";
import { findByProps } from "@webpack";
import { Button, ButtonLooks, ButtonWrapperClasses, Tooltip } from "@webpack/common";
import { Channel } from "discord-types/general";
import { HTMLProps, MouseEventHandler, ReactNode } from "react";
let ChannelTextAreaClasses: Record<"button" | "buttonContainer", string>;
waitFor(["buttonContainer", "channelTextArea"], m => ChannelTextAreaClasses = m);
const ChannelTextAreaClasses = findByProps<Record<"button" | "buttonContainer", string>>("buttonContainer", "channelTextArea");
export interface ChatBarProps {
channel: Channel;

View file

@ -17,14 +17,14 @@
*/
import { mergeDefaults } from "@utils/misc";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { MessageActions, SnowflakeUtils } from "@webpack/common";
import { Message } from "discord-types/general";
import type { PartialDeep } from "type-fest";
import { Argument } from "./types";
const MessageCreator = findByPropsLazy("createBotMessage");
const MessageCreator = findByProps("createBotMessage");
export function generateId() {
return `-${SnowflakeUtils.fromTimestamp(Date.now())}`;

View file

@ -16,10 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { waitFor } from "@webpack";
import { find } from "@webpack";
let NoticesModule: any;
waitFor(m => m.show && m.dismiss && !m.suppressAll, m => NoticesModule = m);
const NoticesModule = find(m => m.show && m.dismiss && !m.suppressAll, m => m);
export const noticesQueue = [] as any[];
export let currentNotice: any = null;

View file

@ -4,10 +4,10 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { Parser } from "@webpack/common";
const CodeContainerClasses = findByPropsLazy("markup", "codeContainer");
const CodeContainerClasses = findByProps("markup", "codeContainer");
/**
* Renders code in a Discord codeblock

View file

@ -25,7 +25,7 @@ import { Margins } from "@utils/margins";
import { classes, isObjectEmpty } from "@utils/misc";
import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize } from "@utils/modal";
import { OptionType, Plugin } from "@utils/types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { findByProps,findComponentByCode } from "@webpack";
import { Button, Clickable, FluxDispatcher, Forms, React, Text, Tooltip, UserStore, UserUtils } from "@webpack/common";
import { User } from "discord-types/general";
import { Constructor } from "type-fest";
@ -41,8 +41,8 @@ import {
} from "./components";
import { openContributorModal } from "./ContributorModal";
const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers");
const AvatarStyles = findByPropsLazy("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar");
const UserSummaryItem = findComponentByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers");
const AvatarStyles = findByProps("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar");
const UserRecord: Constructor<Partial<User>> = proxyLazy(() => UserStore.getCurrentUser().constructor) as any;
interface PluginModalProps extends ModalProps {

View file

@ -33,7 +33,7 @@ import { classes, isObjectEmpty } from "@utils/misc";
import { openModalLazy } from "@utils/modal";
import { useAwaiter } from "@utils/react";
import { Plugin } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { Alerts, Button, Card, Forms, lodash, Parser, React, Select, Text, TextInput, Toasts, Tooltip } from "@webpack/common";
import Plugins from "~plugins";
@ -44,8 +44,8 @@ import { startDependenciesRecursive, startPlugin, stopPlugin } from "../../plugi
const cl = classNameFactory("vc-plugins-");
const logger = new Logger("PluginSettings", "#a6d189");
const InputStyles = findByPropsLazy("inputDefault", "inputWrapper");
const ButtonClasses = findByPropsLazy("button", "disabled", "enabled");
const InputStyles = findByProps("inputDefault", "inputWrapper");
const ButtonClasses = findByProps("button", "disabled", "enabled");
function showErrorToast(message: string) {

View file

@ -19,7 +19,7 @@
import "./Switch.css";
import { classes } from "@utils/misc";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
interface SwitchProps {
checked: boolean;
@ -29,7 +29,7 @@ interface SwitchProps {
const SWITCH_ON = "var(--green-360)";
const SWITCH_OFF = "var(--primary-400)";
const SwitchClasses = findByPropsLazy("slider", "input", "container");
const SwitchClasses = findByProps("slider", "input", "container");
export function Switch({ checked, onChange, disabled }: SwitchProps) {
return (

View file

@ -29,23 +29,22 @@ import { classes } from "@utils/misc";
import { openModal } from "@utils/modal";
import { showItemInFolder } from "@utils/native";
import { useAwaiter } from "@utils/react";
import { findByPropsLazy, findLazy } from "@webpack";
import { find, findComponent } from "@webpack";
import { Button, Card, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from "@webpack/common";
import type { ComponentType, Ref, SyntheticEvent } from "react";
import type { Ref, SyntheticEvent } from "react";
import { AddonCard } from "./AddonCard";
import { SettingsTab, wrapTab } from "./shared";
type FileInput = ComponentType<{
type FileInputProps = {
ref: Ref<HTMLInputElement>;
onChange: (e: SyntheticEvent<HTMLInputElement>) => void;
multiple?: boolean;
filters?: { name?: string; extensions: string[]; }[];
}>;
};
const InviteActions = findByPropsLazy("resolveInvite");
const FileInput: FileInput = findLazy(m => m.prototype?.activateUploadDialogue && m.prototype.setRef);
const TextAreaProps = findLazy(m => typeof m.textarea === "string");
const FileInput = findComponent<FileInputProps>(m => m.prototype?.activateUploadDialogue && m.prototype.setRef);
const TextAreaProps = find(m => typeof m.textarea === "string");
const cl = classNameFactory("vc-settings-theme-");

View file

@ -21,12 +21,12 @@ import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByCodeLazy, findByPropsLazy } from "@webpack";
import { findByCode, findByProps } from "@webpack";
type AnonUpload = Upload & { anonymise?: boolean; };
const ActionBarIcon = findByCodeLazy(".actionBarIcon)");
const UploadDraft = findByPropsLazy("popFirstFile", "update");
const ActionBarIcon = findByCode(".actionBarIcon)");
const UploadDraft = findByProps("popFirstFile", "update");
const enum Methods {
Random,

View file

@ -20,10 +20,10 @@ import { popNotice, showNotice } from "@api/Notices";
import { Link } from "@components/Link";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { ApplicationAssetUtils, FluxDispatcher, Forms, Toasts } from "@webpack/common";
const RpcUtils = findByPropsLazy("fetchApplicationsRPC", "getRemoteIconURL");
const RpcUtils = findByProps("fetchApplicationsRPC", "getRemoteIconURL");
async function lookupAsset(applicationId: string, key: string): Promise<string> {
return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];

View file

@ -17,15 +17,15 @@
*/
import ErrorBoundary from "@components/ErrorBoundary";
import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
import { findByProps, findComponentByCode, findStore } from "@webpack";
import { useStateFromStores } from "@webpack/common";
import type { CSSProperties } from "react";
import { ExpandedGuildFolderStore, settings } from ".";
const ChannelRTCStore = findStoreLazy("ChannelRTCStore");
const Animations = findByPropsLazy("a", "animated", "useTransition");
const GuildsBar = findComponentByCodeLazy('("guildsnav")');
const ChannelRTCStore = findStore("ChannelRTCStore");
const Animations = findByProps("a", "animated", "useTransition");
const GuildsBar = findComponentByCode('("guildsnav")');
export default ErrorBoundary.wrap(guildsBarProps => {
const expandedFolders = useStateFromStores([ExpandedGuildFolderStore], () => ExpandedGuildFolderStore.getExpandedFolders());

View file

@ -19,7 +19,7 @@
import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findStoreLazy } from "@webpack";
import { findByProps, findStore } from "@webpack";
import { FluxDispatcher, i18n } from "@webpack/common";
import FolderSideBar from "./FolderSideBar";
@ -30,10 +30,10 @@ enum FolderIconDisplay {
MoreThanOneFolderExpanded
}
const { GuildsTree } = findByPropsLazy("GuildsTree");
const SortedGuildStore = findStoreLazy("SortedGuildStore");
export const ExpandedGuildFolderStore = findStoreLazy("ExpandedGuildFolderStore");
const FolderUtils = findByPropsLazy("move", "toggleGuildFolderExpand");
const { GuildsTree } = findByProps("GuildsTree");
const SortedGuildStore = findStore("SortedGuildStore");
export const ExpandedGuildFolderStore = findStore("ExpandedGuildFolderStore");
const FolderUtils = findByProps("move", "toggleGuildFolderExpand");
let lastGuildId = null as string | null;
let dispatchingFoldersClose = false;

View file

@ -20,9 +20,9 @@ import { Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
import { canonicalizeMatch } from "@utils/patches";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
const UserPopoutSectionCssClasses = findByPropsLazy("section", "lastSection");
const UserPopoutSectionCssClasses = findByProps("section", "lastSection");
export default definePlugin({
name: "BetterNotesBox",

View file

@ -7,10 +7,10 @@
import { Devs } from "@utils/constants";
import { getCurrentGuild } from "@utils/discord";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { Clipboard, GuildStore, Menu, PermissionStore, TextAndImagesSettingsStores } from "@webpack/common";
const GuildSettingsActions = findByPropsLazy("open", "selectRole", "updateGuild");
const GuildSettingsActions = findByProps("open", "selectRole", "updateGuild");
function PencilIcon() {
return (

View file

@ -21,20 +21,20 @@ import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findExportedComponentLazy, findStoreLazy } from "@webpack";
import { findByProps, findExportedComponent, findStore } from "@webpack";
import { React, RestAPI, Tooltip } from "@webpack/common";
import { RenameButton } from "./components/RenameButton";
import { Session, SessionInfo } from "./types";
import { fetchNamesFromDataStore, getDefaultName, GetOsColor, GetPlatformIcon, savedSessionsCache, saveSessionsToDataStore } from "./utils";
const AuthSessionsStore = findStoreLazy("AuthSessionsStore");
const UserSettingsModal = findByPropsLazy("saveAccountChanges", "open");
const AuthSessionsStore = findStore("AuthSessionsStore");
const UserSettingsModal = findByProps("saveAccountChanges", "open");
const TimestampClasses = findByPropsLazy("timestampTooltip", "blockquoteContainer");
const SessionIconClasses = findByPropsLazy("sessionIcon");
const TimestampClasses = findByProps("timestampTooltip", "blockquoteContainer");
const SessionIconClasses = findByProps("sessionIcon");
const BlobMask = findExportedComponentLazy("BlobMask");
const BlobMask = findExportedComponent("BlobMask");
const settings = definePluginSettings({
backgroundCheck: {

View file

@ -9,14 +9,14 @@ import { classNameFactory } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { ComponentDispatch, FocusLock, i18n, Menu, useEffect, useRef } from "@webpack/common";
import type { HTMLAttributes, ReactElement } from "react";
type SettingsEntry = { section: string, label: string; };
const cl = classNameFactory("");
const Classes = findByPropsLazy("animating", "baseLayer", "bg", "layer", "layers");
const Classes = findByProps("animating", "baseLayer", "bg", "layer", "layers");
const settings = definePluginSettings({
disableFade: {

View file

@ -16,9 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { findStoreLazy } from "@webpack";
import { findStore } from "@webpack";
import * as t from "./types/stores";
export const ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore = findStoreLazy("ApplicationStreamPreviewStore");
export const ApplicationStreamingStore: t.ApplicationStreamingStore = findStoreLazy("ApplicationStreamingStore");
export const ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore = findStore("ApplicationStreamPreviewStore");
export const ApplicationStreamingStore: t.ApplicationStreamingStore = findStore("ApplicationStreamingStore");

View file

@ -11,10 +11,10 @@ import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins";
import { classes } from "@utils/misc";
import definePlugin, { OptionType, StartAt } from "@utils/types";
import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
import { findByProps, findComponentByCode, findStore } from "@webpack";
import { Button, Forms, useStateFromStores } from "@webpack/common";
const ColorPicker = findComponentByCodeLazy(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
const ColorPicker = findComponentByCode(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
const colorPresets = [
"#1E1514", "#172019", "#13171B", "#1C1C28", "#402D2D",
@ -30,14 +30,14 @@ function onPickColor(color: number) {
updateColorVars(hexColor);
}
const { saveClientTheme } = findByPropsLazy("saveClientTheme");
const { saveClientTheme } = findByProps("saveClientTheme");
function setTheme(theme: string) {
saveClientTheme({ theme });
}
const ThemeStore = findStoreLazy("ThemeStore");
const NitroThemeStore = findStoreLazy("ClientThemesBackgroundStore");
const ThemeStore = findStore("ThemeStore");
const NitroThemeStore = findStore("ClientThemesBackgroundStore");
function ThemeSettings() {
const theme = useStateFromStores([ThemeStore], () => ThemeStore.theme);

View file

@ -21,7 +21,7 @@ import { relaunch } from "@utils/native";
import { canonicalizeMatch, canonicalizeReplace, canonicalizeReplacement } from "@utils/patches";
import definePlugin from "@utils/types";
import * as Webpack from "@webpack";
import { extract, filters, findAll, search } from "@webpack";
import { cacheFindAll, extract, filters, search } from "@webpack";
import { React, ReactDOM } from "@webpack/common";
import type { ComponentType } from "react";
@ -42,7 +42,7 @@ export default definePlugin({
const cacheKey = String(filterProps);
if (cache.has(cacheKey)) return cache.get(cacheKey);
const matches = findAll(filterFactory(...filterProps));
const matches = cacheFindAll(filterFactory(...filterProps));
const result = (() => {
switch (matches.length) {
@ -73,13 +73,13 @@ export default definePlugin({
wpex: extract,
wpexs: (code: string) => extract(Webpack.findModuleId(code)!),
find,
findAll,
findAll: cacheFindAll,
findByProps,
findAllByProps: (...props: string[]) => findAll(filters.byProps(...props)),
findAllByProps: (...props: string[]) => cacheFindAll(filters.byProps(...props)),
findByCode: newFindWrapper(filters.byCode),
findAllByCode: (code: string) => findAll(filters.byCode(code)),
findAllByCode: (code: string) => cacheFindAll(filters.byCode(code)),
findComponentByCode: newFindWrapper(filters.componentByCode),
findAllComponentsByCode: (...code: string[]) => findAll(filters.componentByCode(...code)),
findAllComponentsByCode: (...code: string[]) => cacheFindAll(filters.componentByCode(...code)),
findExportedComponent: (...props: string[]) => findByProps(...props)[props[0]],
findStore: newFindWrapper(filters.byStoreName),
PluginsApi: Vencord.Plugins,

View file

@ -23,25 +23,14 @@ import { Logger } from "@utils/Logger";
import { closeAllModals } from "@utils/modal";
import definePlugin, { OptionType } from "@utils/types";
import { maybePromptToUpdate } from "@utils/updater";
import { filters, findBulk, proxyLazyWebpack } from "@webpack";
import { findByProps } from "@webpack";
import { FluxDispatcher, NavigationRouter, SelectedChannelStore } from "@webpack/common";
const CrashHandlerLogger = new Logger("CrashHandler");
const { ModalStack, DraftManager, DraftType, closeExpressionPicker } = proxyLazyWebpack(() => {
const modules = findBulk(
filters.byProps("pushLazy", "popAll"),
filters.byProps("clearDraft", "saveDraft"),
filters.byProps("DraftType"),
filters.byProps("closeExpressionPicker", "openExpressionPicker"),
);
return {
ModalStack: modules[0],
DraftManager: modules[1],
DraftType: modules[2]?.DraftType,
closeExpressionPicker: modules[3]?.closeExpressionPicker,
};
});
const ModalStack = findByProps("pushLazy", "popAll");
const DraftManager = findByProps("clearDraft", "saveDraft");
const { DraftType } = findByProps("DraftType");
const { closeExpressionPicker } = findByProps("closeExpressionPicker", "openExpressionPicker");
const settings = definePluginSettings({
attemptToPreventCrashes: {

View file

@ -22,12 +22,12 @@ import { Devs } from "@utils/constants";
import { isTruthy } from "@utils/guards";
import { useAwaiter } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types";
import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { findByCode, findByProps, findComponentByCode } from "@webpack";
import { ApplicationAssetUtils, FluxDispatcher, Forms, GuildStore, React, SelectedChannelStore, SelectedGuildStore, UserStore } from "@webpack/common";
const useProfileThemeStyle = findByCodeLazy("profileThemeStyle:", "--profile-gradient-primary-color");
const ActivityComponent = findComponentByCodeLazy("onOpenGameProfile");
const ActivityClassName = findByPropsLazy("activity", "buttonColor");
const useProfileThemeStyle = findByCode("profileThemeStyle:", "--profile-gradient-primary-color");
const ActivityComponent = findComponentByCode("onOpenGameProfile");
const ActivityClassName = findByProps("activity", "buttonColor");
async function getApplicationAsset(key: string): Promise<string> {
if (/https?:\/\/(cdn|media)\.discordapp\.(com|net)\/attachments\//.test(key)) return "mp:" + key.replace(/https?:\/\/(cdn|media)\.discordapp\.(com|net)\//, "");

View file

@ -9,7 +9,7 @@ import "./ui/styles.css";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { UserStore } from "@webpack/common";
import { CDN_URL, RAW_SKU_ID, SKU_ID } from "./lib/constants";
@ -20,7 +20,7 @@ import { settings } from "./settings";
import { setDecorationGridDecoration, setDecorationGridItem } from "./ui/components";
import DecorSection from "./ui/components/DecorSection";
const { isAnimatedAvatarDecoration } = findByPropsLazy("isAnimatedAvatarDecoration");
const { isAnimatedAvatarDecoration } = findByProps("isAnimatedAvatarDecoration");
export interface AvatarDecoration {
asset: string;
skuId: string;

View file

@ -5,7 +5,7 @@
*/
import { Flex } from "@components/Flex";
import { findByCodeLazy } from "@webpack";
import { findByCode } from "@webpack";
import { Button, useEffect } from "@webpack/common";
import { useAuthorizationStore } from "../../lib/stores/AuthorizationStore";
@ -13,7 +13,7 @@ import { useCurrentUserDecorationsStore } from "../../lib/stores/CurrentUserDeco
import { cl } from "../";
import { openChangeDecorationModal } from "../modals/ChangeDecorationModal";
const CustomizationSection = findByCodeLazy(".customizationSectionBackground");
const CustomizationSection = findByCode(".customizationSectionBackground");
interface DecorSectionProps {
hideTitle?: boolean;

View file

@ -5,13 +5,13 @@
*/
import { classes } from "@utils/misc";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { React } from "@webpack/common";
import { cl } from "../";
import Grid, { GridProps } from "./Grid";
const ScrollerClasses = findByPropsLazy("managedReactiveScroller");
const ScrollerClasses = findByProps("managedReactiveScroller");
type Section<SectionT, ItemT> = SectionT & {
items: Array<ItemT>;

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { findComponentByCode, LazyComponentWebpack } from "@webpack";
import { filters, findComponent } from "@webpack";
import { React } from "@webpack/common";
import type { ComponentType, HTMLProps, PropsWithChildren } from "react";
@ -18,8 +18,7 @@ type DecorationGridItemComponent = ComponentType<PropsWithChildren<HTMLProps<HTM
export let DecorationGridItem: DecorationGridItemComponent;
export const setDecorationGridItem = v => DecorationGridItem = v;
export const AvatarDecorationModalPreview = LazyComponentWebpack(() => {
const component = findComponentByCode(".shopPreviewBanner");
export const AvatarDecorationModalPreview = findComponent(filters.componentByCode(".shopPreviewBanner"), component => {
return React.memo(component);
});

View file

@ -5,10 +5,10 @@
*/
import { classNameFactory } from "@api/Styles";
import { extractAndLoadChunksLazy, findByPropsLazy } from "@webpack";
import { extractAndLoadChunksLazy, findByProps } from "@webpack";
export const cl = classNameFactory("vc-decor-");
export const DecorationModalStyles = findByPropsLazy("modalFooterShopButton");
export const DecorationModalStyles = findByProps("modalFooterShopButton");
export const requireAvatarDecorationModal = extractAndLoadChunksLazy(["openAvatarDecorationModal:"]);
export const requireCreateStickerModal = extractAndLoadChunksLazy(["stickerInspected]:"]);

View file

@ -10,7 +10,7 @@ import { openInviteModal } from "@utils/discord";
import { Margins } from "@utils/margins";
import { classes } from "@utils/misc";
import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { findComponentByCodeLazy } from "@webpack";
import { findComponentByCode } from "@webpack";
import { Alerts, Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Parser, Text, Tooltip, useEffect, UserStore, UserUtils, useState } from "@webpack/common";
import { User } from "discord-types/general";
@ -29,7 +29,7 @@ import SectionedGridList from "../components/SectionedGridList";
import { openCreateDecorationModal } from "./CreateDecorationModal";
import { openGuidelinesModal } from "./GuidelinesModal";
const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers");
const UserSummaryItem = findComponentByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers");
function usePresets() {
const [presets, setPresets] = useState<Preset[]>([]);

View file

@ -9,7 +9,7 @@ import { Link } from "@components/Link";
import { openInviteModal } from "@utils/discord";
import { Margins } from "@utils/margins";
import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { findByProps, findComponentByCode } from "@webpack";
import { Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Text, TextInput, useEffect, useMemo, UserStore, useState } from "@webpack/common";
import { GUILD_ID, INVITE_KEY, RAW_SKU_ID } from "../../lib/constants";
@ -17,9 +17,9 @@ import { useCurrentUserDecorationsStore } from "../../lib/stores/CurrentUserDeco
import { cl, DecorationModalStyles, requireAvatarDecorationModal, requireCreateStickerModal } from "../";
import { AvatarDecorationModalPreview } from "../components";
const FileUpload = findComponentByCodeLazy("fileUploadInput,");
const FileUpload = findComponentByCode("fileUploadInput,");
const { default: HelpMessage, HelpMessageTypes } = findByPropsLazy("HelpMessageTypes");
const { default: HelpMessage, HelpMessageTypes } = findByProps("HelpMessageTypes");
function useObjectURL(object: Blob | MediaSource | null) {
const [url, setUrl] = useState<string | null>(null);

View file

@ -22,7 +22,7 @@ import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import { canonicalizeMatch, canonicalizeReplace } from "@utils/patches";
import definePlugin, { OptionType } from "@utils/types";
import { filters, findAll, search } from "@webpack";
import { cacheFind, filters, search } from "@webpack";
const PORT = 8485;
const NAV_ID = "dev-companion-reconnect";
@ -201,22 +201,22 @@ function initWs(isManual = false) {
let results: any[];
switch (type.replace("find", "").replace("Lazy", "")) {
case "":
results = findAll(parsedArgs[0]);
results = cacheFind(parsedArgs[0]);
break;
case "ByProps":
results = findAll(filters.byProps(...parsedArgs));
results = cacheFind(filters.byProps(...parsedArgs));
break;
case "Store":
results = findAll(filters.byStoreName(parsedArgs[0]));
results = cacheFind(filters.byStoreName(parsedArgs[0]));
break;
case "ByCode":
results = findAll(filters.byCode(...parsedArgs));
results = cacheFind(filters.byCode(...parsedArgs));
break;
case "ModuleId":
results = Object.keys(search(parsedArgs[0]));
break;
case "ComponentByCode":
results = findAll(filters.componentByCode(...parsedArgs));
results = cacheFind(filters.componentByCode(...parsedArgs));
break;
default:
return reply("Unknown Find Type " + type);

View file

@ -23,12 +23,12 @@ import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins";
import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal";
import definePlugin from "@utils/types";
import { findByPropsLazy, findStoreLazy } from "@webpack";
import { findByProps, findStore } from "@webpack";
import { EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
import { Promisable } from "type-fest";
const StickersStore = findStoreLazy("StickersStore");
const EmojiManager = findByPropsLazy("fetchEmoji", "uploadEmoji", "deleteEmoji");
const StickersStore = findStore("StickersStore");
const EmojiManager = findByProps("fetchEmoji", "uploadEmoji", "deleteEmoji");
interface Sticker {
t: "Sticker";

View file

@ -22,10 +22,10 @@ import { ErrorCard } from "@components/ErrorCard";
import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { Forms, React } from "@webpack/common";
const KbdStyles = findByPropsLazy("key", "removeBuildOverride");
const KbdStyles = findByProps("key", "removeBuildOverride");
const settings = definePluginSettings({
enableIsStaff: {

View file

@ -23,7 +23,7 @@ import { ApngBlendOp, ApngDisposeOp, importApngJs } from "@utils/dependencies";
import { getCurrentGuild } from "@utils/discord";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findStoreLazy, proxyLazyWebpack } from "@webpack";
import { findByProps, findStore, webpackDependantLazy } from "@webpack";
import { Alerts, ChannelStore, EmojiStore, FluxDispatcher, Forms, IconUtils, lodash, Parser, PermissionsBits, PermissionStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common";
import type { CustomEmoji } from "@webpack/types";
import type { Message } from "discord-types/general";
@ -31,14 +31,14 @@ import { applyPalette, GIFEncoder, quantize } from "gifenc";
import type { ReactElement, ReactNode } from "react";
const DRAFT_TYPE = 0;
const StickerStore = findStoreLazy("StickersStore") as {
const StickerStore = findStore("StickersStore") as {
getPremiumPacks(): StickerPack[];
getAllGuildStickers(): Map<string, Sticker[]>;
getStickerById(id: string): Sticker | undefined;
};
const UserSettingsProtoStore = findStoreLazy("UserSettingsProtoStore");
const ProtoUtils = findByPropsLazy("BINARY_READ_OPTIONS");
const UserSettingsProtoStore = findStore("UserSettingsProtoStore");
const ProtoUtils = findByProps("BINARY_READ_OPTIONS");
function searchProtoClassField(localName: string, protoClass: any) {
const field = protoClass?.fields?.find((field: any) => field.localName === localName);
@ -48,9 +48,9 @@ function searchProtoClassField(localName: string, protoClass: any) {
return fieldGetter?.();
}
const PreloadedUserSettingsActionCreators = proxyLazyWebpack(() => UserSettingsActionCreators.PreloadedUserSettingsActionCreators);
const AppearanceSettingsActionCreators = proxyLazyWebpack(() => searchProtoClassField("appearance", PreloadedUserSettingsActionCreators.ProtoClass));
const ClientThemeSettingsActionsCreators = proxyLazyWebpack(() => searchProtoClassField("clientThemeSettings", AppearanceSettingsActionCreators));
const PreloadedUserSettingsActionCreators = webpackDependantLazy(() => UserSettingsActionCreators.PreloadedUserSettingsActionCreators);
const AppearanceSettingsActionCreators = webpackDependantLazy(() => searchProtoClassField("appearance", PreloadedUserSettingsActionCreators.ProtoClass));
const ClientThemeSettingsActionsCreators = webpackDependantLazy(() => searchProtoClassField("clientThemeSettings", AppearanceSettingsActionCreators));
const enum EmojiIntentions {

View file

@ -20,7 +20,7 @@ import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { useCallback, useEffect, useRef, useState } from "@webpack/common";
interface SearchBarComponentProps {
@ -35,7 +35,7 @@ interface SearchBarComponentProps {
}
type TSearchBarComponent =
React.FC<SearchBarComponentProps> & { Sizes: Record<"SMALL" | "MEDIUM" | "LARGE", string>; };
React.ComponentType<SearchBarComponentProps> & { Sizes: Record<"SMALL" | "MEDIUM" | "LARGE", string>; };
interface Gif {
format: number;
@ -60,7 +60,7 @@ interface Instance {
}
const containerClasses: { searchBar: string; } = findByPropsLazy("searchBar", "searchBarFullRow");
const containerClasses: { searchBar: string; } = findByProps("searchBar", "searchBarFullRow");
export const settings = definePluginSettings({
searchOption: {

View file

@ -19,11 +19,11 @@
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { RestAPI, UserStore } from "@webpack/common";
const FriendInvites = findByPropsLazy("createFriendInvite");
const { uuid4 } = findByPropsLazy("uuid4");
const FriendInvites = findByProps("createFriendInvite");
const { uuid4 } = findByProps("uuid4");
export default definePlugin({
name: "FriendInvites",

View file

@ -8,14 +8,14 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { getCurrentChannel } from "@utils/discord";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { Heading, React, RelationshipStore, Text } from "@webpack/common";
const container = findByPropsLazy("memberSinceWrapper");
const { getCreatedAtDate } = findByPropsLazy("getCreatedAtDate");
const clydeMoreInfo = findByPropsLazy("clydeMoreInfo");
const locale = findByPropsLazy("getLocale");
const lastSection = findByPropsLazy("lastSection");
const container = findByProps("memberSinceWrapper");
const { getCreatedAtDate } = findByProps("getCreatedAtDate");
const clydeMoreInfo = findByProps("clydeMoreInfo");
const locale = findByProps("getLocale");
const lastSection = findByProps("lastSection");
export default definePlugin({
name: "FriendsSince",

View file

@ -21,12 +21,12 @@ import { disableStyle, enableStyle } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findComponentByCodeLazy } from "@webpack";
import { findComponentByCode } from "@webpack";
import { StatusSettingsStores } from "@webpack/common";
import style from "./style.css?managed";
const Button = findComponentByCodeLazy("Button.Sizes.NONE,disabled:");
const Button = findComponentByCode("Button.Sizes.NONE,disabled:");
function makeIcon(showCurrentGame?: boolean) {
const { oldIcon } = settings.use(["oldIcon"]);

View file

@ -19,9 +19,9 @@
import { Devs } from "@utils/constants";
import { insertTextIntoChatInputBox } from "@utils/discord";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
const { closeExpressionPicker } = findByPropsLazy("closeExpressionPicker");
const { closeExpressionPicker } = findByProps("closeExpressionPicker");
export default definePlugin({
name: "GifPaste",

View file

@ -19,7 +19,7 @@
import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { ContextMenuApi, FluxDispatcher, Menu, MessageActions } from "@webpack/common";
import { Channel, Message } from "discord-types/general";
@ -49,7 +49,7 @@ const settings = definePluginSettings({
unholyMultiGreetEnabled?: boolean;
}>();
const { WELCOME_STICKERS } = findByPropsLazy("WELCOME_STICKERS");
const { WELCOME_STICKERS } = findByProps("WELCOME_STICKERS");
function greet(channel: Channel, message: Message, stickers: string[]) {
const options = MessageActions.getSendMessageOptionsForReply({

View file

@ -11,7 +11,7 @@ import { Flex } from "@components/Flex";
import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins";
import definePlugin, { OptionType } from "@utils/types";
import { findStoreLazy } from "@webpack";
import { findStore } from "@webpack";
import { Button, Forms, showToast, StatusSettingsStores, TextInput, Toasts, Tooltip, useEffect, useState } from "webpack/common";
const enum ActivitiesTypes {
@ -25,7 +25,7 @@ interface IgnoredActivity {
type: ActivitiesTypes;
}
const RunningGameStore = findStoreLazy("RunningGameStore");
const RunningGameStore = findStore("RunningGameStore");
function ToggleIcon(activity: IgnoredActivity, tooltipText: string, path: string, fill: string) {
return (

View file

@ -36,7 +36,7 @@ export interface MagnifierProps {
const cl = classNameFactory("vc-imgzoom-");
export const Magnifier: React.FC<MagnifierProps> = ({ instance, size: initialSize, zoom: initalZoom }) => {
export const Magnifier: React.ComponentType<MagnifierProps> = ({ instance, size: initialSize, zoom: initalZoom }) => {
const [ready, setReady] = useState(false);
const [lensPosition, setLensPosition] = useState<Vec2>({ x: 0, y: 0 });

View file

@ -19,11 +19,11 @@
import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByProps, findStoreLazy } from "@webpack";
import { findByProps, findStore } from "@webpack";
import { ChannelStore, FluxDispatcher, GuildStore, RelationshipStore, SnowflakeUtils, UserStore } from "@webpack/common";
import { Settings } from "Vencord";
const UserAffinitiesStore = findStoreLazy("UserAffinitiesStore");
const UserAffinitiesStore = findStore("UserAffinitiesStore");
interface UserAffinity {
user_id: string;

View file

@ -21,7 +21,7 @@ import { Link } from "@components/Link";
import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { ApplicationAssetUtils, FluxDispatcher, Forms } from "@webpack/common";
interface ActivityAssets {
@ -85,7 +85,7 @@ const placeholderId = "2a96cbd8b46e442fc41c2b86b821562f";
const logger = new Logger("LastFMRichPresence");
const presenceStore = findByPropsLazy("getLocalPresence");
const presenceStore = findByProps("getLocalPresence");
async function getApplicationAsset(key: string): Promise<string> {
return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];

View file

@ -23,13 +23,13 @@ import { classNameFactory } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findStoreLazy } from "@webpack";
import { findStore } from "@webpack";
import { FluxStore } from "@webpack/types";
import { MemberCount } from "./MemberCount";
export const GuildMemberCountStore = findStoreLazy("GuildMemberCountStore") as FluxStore & { getMemberCount(guildId: string): number | null; };
export const ChannelMemberStore = findStoreLazy("ChannelMemberStore") as FluxStore & {
export const GuildMemberCountStore = findStore("GuildMemberCountStore") as FluxStore & { getMemberCount(guildId: string): number | null; };
export const ChannelMemberStore = findStore("ChannelMemberStore") as FluxStore & {
getProps(guildId: string, channelId: string): { groups: { count: number; id: string; }[]; };
};

View file

@ -20,7 +20,7 @@ import { addClickListener, removeClickListener } from "@api/MessageEvents";
import { definePluginSettings, Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { FluxDispatcher, PermissionsBits, PermissionStore, UserStore } from "@webpack/common";
let isDeletePressed = false;
@ -60,8 +60,8 @@ export default definePlugin({
settings,
start() {
const MessageActions = findByPropsLazy("deleteMessage", "startEditMessage");
const EditStore = findByPropsLazy("isEditing", "isEditingAny");
const MessageActions = findByProps("deleteMessage", "startEditMessage");
const EditStore = findByProps("isEditing", "isEditingAny");
document.addEventListener("keydown", keydown);
document.addEventListener("keyup", keyup);

View file

@ -23,7 +23,7 @@ import { Devs } from "@utils/constants.js";
import { classes } from "@utils/misc";
import { Queue } from "@utils/Queue";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { findByProps,findComponentByCode } from "@webpack";
import {
Button,
ChannelStore,
@ -46,12 +46,12 @@ const messageCache = new Map<string, {
fetched: boolean;
}>();
const Embed = findComponentByCodeLazy(".inlineMediaEmbed");
const AutoModEmbed = findComponentByCodeLazy(".withFooter]:", "childrenMessageContent:");
const ChannelMessage = findComponentByCodeLazy("renderSimpleAccessories)");
const Embed = findComponentByCode(".inlineMediaEmbed");
const AutoModEmbed = findComponentByCode(".withFooter]:", "childrenMessageContent:");
const ChannelMessage = findComponentByCode("renderSimpleAccessories)");
const SearchResultClasses = findByPropsLazy("message", "searchResult");
const EmbedClasses = findByPropsLazy("embedAuthorIcon", "embedAuthor", "embedAuthor");
const SearchResultClasses = findByProps("message", "searchResult");
const EmbedClasses = findByProps("embedAuthorIcon", "embedAuthor", "embedAuthor");
const messageLinkRegex = /(?<!<)https?:\/\/(?:\w+\.)?discord(?:app)?\.com\/channels\/(?:\d{17,20}|@me)\/(\d{17,20})\/(\d{17,20})/g;
const tenorRegex = /^https:\/\/(?:www\.)?tenor\.com\//;

View file

@ -25,13 +25,13 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { ChannelStore, FluxDispatcher, i18n, Menu, Parser, Timestamp, UserStore } from "@webpack/common";
import overlayStyle from "./deleteStyleOverlay.css?managed";
import textStyle from "./deleteStyleText.css?managed";
const styles = findByPropsLazy("edited", "communicationDisabled", "isSystemMessage");
const styles = findByProps("edited", "communicationDisabled", "isSystemMessage");
function addDeleteStyle() {
if (Settings.plugins.MessageLogger.deleteStyle === "text") {

View file

@ -21,7 +21,7 @@ import { Flex } from "@components/Flex";
import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findLazy } from "@webpack";
import { find, findByProps } from "@webpack";
import { Card, ChannelStore, Forms, GuildStore, PermissionsBits, Switch, TextInput, Tooltip, useState } from "@webpack/common";
import { RC } from "@webpack/types";
import { Channel, Message, User } from "discord-types/general";
@ -54,11 +54,11 @@ interface TagSettings {
}
// PermissionStore.computePermissions is not the same function and doesn't work here
const PermissionUtil = findByPropsLazy("computePermissions", "canEveryoneRole") as {
const PermissionUtil = findByProps("computePermissions", "canEveryoneRole") as {
computePermissions({ ...args }): bigint;
};
const Tag = findLazy(m => m.Types?.[0] === "BOT") as RC<{ type?: number, className?: string, useRemSizes?: boolean; }> & { Types: Record<string, number>; };
const Tag = find(m => m.Types?.[0] === "BOT") as RC<{ type?: number, className?: string, useRemSizes?: boolean; }> & { Types: Record<string, number>; };
const isWebhook = (message: Message, user: User) => !!message?.webhookId && user.isNonUserBot();

View file

@ -19,15 +19,15 @@
import { Devs } from "@utils/constants";
import { isNonNullish } from "@utils/guards";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, UserStore } from "@webpack/common";
import { Channel, User } from "discord-types/general";
const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel");
const UserUtils = findByPropsLazy("getGlobalName");
const SelectedChannelActionCreators = findByProps("selectPrivateChannel");
const UserUtils = findByProps("getGlobalName");
const ProfileListClasses = findByPropsLazy("emptyIconFriends", "emptyIconGuilds");
const GuildLabelClasses = findByPropsLazy("guildNick", "guildAvatarWithoutIcon");
const ProfileListClasses = findByProps("emptyIconFriends", "emptyIconGuilds");
const GuildLabelClasses = findByProps("guildNick", "guildAvatarWithoutIcon");
function getGroupDMName(channel: Channel) {
return channel.name ||

View file

@ -16,14 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { definePluginSettings,migratePluginSettings } from "@api/Settings";
import { definePluginSettings, migratePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
const { updateGuildNotificationSettings } = findByPropsLazy("updateGuildNotificationSettings");
const { toggleShowAllChannels } = findByPropsLazy("toggleShowAllChannels");
const { isOptInEnabledForGuild } = findByPropsLazy("isOptInEnabledForGuild");
const { updateGuildNotificationSettings } = findByProps("updateGuildNotificationSettings");
const { toggleShowAllChannels } = findByProps("toggleShowAllChannels");
const { isOptInEnabledForGuild } = findByProps("isOptInEnabledForGuild");
const settings = definePluginSettings({
guild: {

View file

@ -19,9 +19,9 @@
import { Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
const RelationshipStore = findByPropsLazy("getRelationships", "isBlocked");
const RelationshipStore = findByProps("getRelationships", "isBlocked");
export default definePlugin({
name: "NoBlockedMessages",

View file

@ -19,9 +19,9 @@
import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
const MessageRequestStore = findByPropsLazy("getMessageRequestsCount");
const MessageRequestStore = findByProps("getMessageRequestsCount");
const settings = definePluginSettings({
hideFriendRequestsCount: {

View file

@ -18,11 +18,11 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { GuildStore, RestAPI } from "@webpack/common";
const Messages = findByPropsLazy("GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION");
const { InvitesDisabledExperiment } = findByPropsLazy("InvitesDisabledExperiment");
const Messages = findByProps("GUILD_INVITE_DISABLE_ACTION_SHEET_DESCRIPTION");
const { InvitesDisabledExperiment } = findByProps("InvitesDisabledExperiment");
export default definePlugin({
name: "PauseInvitesForever",

View file

@ -18,8 +18,9 @@
import ErrorBoundary from "@components/ErrorBoundary";
import ExpandableHeader from "@components/ExpandableHeader";
import { proxyLazy } from "@utils/lazy";
import { classes } from "@utils/misc";
import { filters, findBulk, proxyLazyWebpack } from "@webpack";
import { findByProps } from "@webpack";
import { i18n, PermissionsBits, Text, Tooltip, useMemo, UserStore } from "@webpack/common";
import type { Guild, GuildMember } from "discord-types/general";
@ -35,13 +36,11 @@ interface UserPermission {
type UserPermissions = Array<UserPermission>;
const Classes = proxyLazyWebpack(() =>
Object.assign({}, ...findBulk(
filters.byProps("roles", "rolePill", "rolePillBorder"),
filters.byProps("roleCircle", "dotBorderBase", "dotBorderColor"),
filters.byProps("roleNameOverflow", "root", "roleName", "roleRemoveButton")
))
) as Record<"roles" | "rolePill" | "rolePillBorder" | "desaturateUserColors" | "flex" | "alignCenter" | "justifyCenter" | "svg" | "background" | "dot" | "dotBorderColor" | "roleCircle" | "dotBorderBase" | "flex" | "alignCenter" | "justifyCenter" | "wrap" | "root" | "role" | "roleRemoveButton" | "roleDot" | "roleFlowerStar" | "roleRemoveIcon" | "roleRemoveIconFocused" | "roleVerifiedIcon" | "roleName" | "roleNameOverflow" | "actionButton" | "overflowButton" | "addButton" | "addButtonIcon" | "overflowRolesPopout" | "overflowRolesPopoutArrowWrapper" | "overflowRolesPopoutArrow" | "popoutBottom" | "popoutTop" | "overflowRolesPopoutHeader" | "overflowRolesPopoutHeaderIcon" | "overflowRolesPopoutHeaderText" | "roleIcon", string>;
const RoleClasses1 = findByProps("roles", "rolePill", "rolePillBorder");
const RoleClasses2 = findByProps("roleCircle", "dotBorderBase", "dotBorderColor");
const RoleClasses3 = findByProps("roleNameOverflow", "root", "roleName", "roleRemoveButton");
const Classes = proxyLazy(() => Object.assign({}, RoleClasses1, RoleClasses2, RoleClasses3));
function UserPermissionsComponent({ guild, guildMember, showBorder }: { guild: Guild; guildMember: GuildMember; showBorder: boolean; }) {
const stns = settings.use(["permissionsSortOrder"]);

View file

@ -20,7 +20,7 @@ import { ApplicationCommandInputType, ApplicationCommandOptionType, Argument, Co
import { Devs } from "@utils/constants";
import { makeLazy } from "@utils/lazy";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { UploadHandler, UserUtils } from "@webpack/common";
import { applyPalette, GIFEncoder, quantize } from "gifenc";
@ -36,7 +36,7 @@ const getFrames = makeLazy(() => Promise.all(
))
);
const UploadStore = findByPropsLazy("getUploads");
const UploadStore = findByProps("getUploads");
function loadImage(source: File | string) {
const isFile = source instanceof File;

View file

@ -6,7 +6,7 @@
import { classNameFactory } from "@api/Styles";
import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModalLazy } from "@utils/modal";
import { extractAndLoadChunksLazy, findComponentByCodeLazy } from "@webpack";
import { extractAndLoadChunksLazy, findComponentByCode } from "@webpack";
import { Button, Forms, Text, TextInput, Toasts, useEffect, useState } from "@webpack/common";
import { DEFAULT_COLOR, SWATCHES } from "../constants";
@ -30,8 +30,8 @@ interface ColorPickerWithSwatchesProps {
renderCustomButton?: () => React.ReactNode;
}
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
const ColorPickerWithSwatches = findComponentByCodeLazy<ColorPickerWithSwatchesProps>("presets,", "customColor:");
const ColorPicker = findComponentByCode<ColorPickerProps>(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)");
const ColorPickerWithSwatches = findComponentByCode<ColorPickerWithSwatchesProps>("presets,", "customColor:");
export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}Promise\.all\((\[\i\.\i\(".+?"\).+?\])\).then\(\i\.bind\(\i,"(.+?)"\)\).{0,50}"UserSettings"/);

View file

@ -11,7 +11,7 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { classes } from "@utils/misc";
import definePlugin, { OptionType, StartAt } from "@utils/types";
import { findByPropsLazy, findStoreLazy } from "@webpack";
import { findByProps, findStore } from "@webpack";
import { ContextMenuApi, FluxDispatcher, Menu, React } from "@webpack/common";
import { Channel } from "discord-types/general";
@ -27,9 +27,9 @@ interface ChannelComponentProps {
}
const headerClasses = findByPropsLazy("privateChannelsHeaderContainer");
const headerClasses = findByProps("privateChannelsHeaderContainer");
export const PrivateChannelSortStore = findStoreLazy("PrivateChannelSortStore") as { getPrivateChannelIds: () => string[]; };
export const PrivateChannelSortStore = findStore("PrivateChannelSortStore") as { getPrivateChannelIds: () => string[]; };
export let instance: any;
export const forceUpdate = () => instance?.props?._forceUpdate?.();

View file

@ -0,0 +1,94 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2023 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 <https://www.gnu.org/licenses/>.
*/
import { definePluginSettings, Settings, useSettings } from "@api/Settings";
import { OptionType } from "@utils/types";
import { findStore } from "@webpack";
export const enum PinOrder {
LastMessage,
Custom
}
export const settings = definePluginSettings({
pinOrder: {
type: OptionType.SELECT,
description: "Which order should pinned DMs be displayed in?",
options: [
{ label: "Most recent message", value: PinOrder.LastMessage, default: true },
{ label: "Custom (right click channels to reorder)", value: PinOrder.Custom }
]
}
});
const PrivateChannelSortStore = findStore("PrivateChannelSortStore");
export let snapshotArray: string[];
let snapshot: Set<string> | undefined;
const getArray = () => (Settings.plugins.PinDMs.pinnedDMs || void 0)?.split(",") as string[] | undefined;
const save = (pins: string[]) => {
snapshot = void 0;
Settings.plugins.PinDMs.pinnedDMs = pins.join(",");
};
const takeSnapshot = () => {
snapshotArray = getArray() ?? [];
return snapshot = new Set<string>(snapshotArray);
};
const requireSnapshot = () => snapshot ?? takeSnapshot();
export function usePinnedDms() {
useSettings(["plugins.PinDMs.pinnedDMs"]);
return requireSnapshot();
}
export function isPinned(id: string) {
return requireSnapshot().has(id);
}
export function togglePin(id: string) {
const snapshot = requireSnapshot();
if (!snapshot.delete(id)) {
snapshot.add(id);
}
save([...snapshot]);
}
export function sortedSnapshot() {
requireSnapshot();
if (settings.store.pinOrder === PinOrder.LastMessage)
return PrivateChannelSortStore.getPrivateChannelIds().filter(isPinned);
return snapshotArray;
}
export function getPinAt(idx: number) {
return sortedSnapshot()[idx];
}
export function movePin(id: string, direction: -1 | 1) {
const pins = getArray()!;
const a = pins.indexOf(id);
const b = a + direction;
[pins[a], pins[b]] = [pins[b], pins[a]];
save(pins);
}

View file

@ -23,11 +23,11 @@ import { Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findStoreLazy } from "@webpack";
import { findByProps, findStore } from "@webpack";
import { PresenceStore, Tooltip, UserStore } from "@webpack/common";
import { User } from "discord-types/general";
const SessionsStore = findStoreLazy("SessionsStore");
const SessionsStore = findStore("SessionsStore");
function Icon(path: string, opts?: { viewBox?: string; width?: number; height?: number; }) {
return ({ color, tooltip, small }: { color: string; tooltip: string; small: boolean; }) => (
@ -55,7 +55,7 @@ const Icons = {
};
type Platform = keyof typeof Icons;
const StatusUtils = findByPropsLazy("useStatusFillColor", "StatusTypes");
const StatusUtils = findByProps("useStatusFillColor", "StatusTypes");
const PlatformIcon = ({ platform, status, small }: { platform: Platform, status: string; small: boolean; }) => {
const tooltip = platform[0].toUpperCase() + platform.slice(1);

View file

@ -20,11 +20,11 @@ import { addChatBarButton, ChatBarButton, removeChatBarButton } from "@api/ChatB
import { generateId, sendBotMessage } from "@api/Commands";
import { Devs } from "@utils/constants";
import definePlugin, { StartAt } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { DraftStore, DraftType, SelectedChannelStore, UserStore, useStateFromStores } from "@webpack/common";
import { MessageAttachment } from "discord-types/general";
const UploadStore = findByPropsLazy("getUploads");
const UploadStore = findByProps("getUploads");
const getDraft = (channelId: string) => DraftStore.getDraft(channelId, DraftType.ChannelMessage);

View file

@ -18,14 +18,14 @@
import ErrorBoundary from "@components/ErrorBoundary";
import { classes } from "@utils/misc";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { UserStore } from "@webpack/common";
import { Message } from "discord-types/general";
import { useFormattedPronouns } from "../pronoundbUtils";
import { settings } from "../settings";
const styles: Record<string, string> = findByPropsLazy("timestampInline");
const styles: Record<string, string> = findByProps("timestampInline");
const AUTO_MODERATION_ACTION = 24;

View file

@ -19,11 +19,11 @@
import { definePluginSettings, Settings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { ChannelStore, FluxDispatcher as Dispatcher, MessageStore, PermissionsBits, PermissionStore, SelectedChannelStore, UserStore } from "@webpack/common";
import { Message } from "discord-types/general";
const Kangaroo = findByPropsLazy("jumpToMessage");
const Kangaroo = findByProps("jumpToMessage");
const isMac = navigator.platform.includes("Mac"); // bruh
let replyIdx = -1;

View file

@ -21,10 +21,10 @@ import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { Button, Menu, Tooltip, useEffect, useState } from "@webpack/common";
const ChannelRowClasses = findByPropsLazy("modeConnected", "modeLocked", "icon");
const ChannelRowClasses = findByProps("modeConnected", "modeLocked", "icon");
let currentShouldViewServerHome = false;
const shouldViewServerHomeStates = new Set<React.Dispatch<React.SetStateAction<boolean>>>();

View file

@ -18,10 +18,10 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
const SpoilerClasses = findByPropsLazy("spoilerContent");
const MessagesClasses = findByPropsLazy("messagesWrapper", "messages");
const SpoilerClasses = findByProps("spoilerContent");
const MessagesClasses = findByProps("messagesWrapper", "messages");
export default definePlugin({
name: "RevealAllSpoilers",

View file

@ -7,14 +7,14 @@
import { DataStore } from "@api/index";
import { Logger } from "@utils/Logger";
import { openModal } from "@utils/modal";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { showToast, Toasts, UserStore } from "@webpack/common";
import { ReviewDBAuth } from "./entities";
const DATA_STORE_KEY = "rdb-auth";
const { OAuth2AuthorizeModal } = findByPropsLazy("OAuth2AuthorizeModal");
const { OAuth2AuthorizeModal } = findByProps("OAuth2AuthorizeModal");
export let Auth: ReviewDBAuth = {};

View file

@ -18,10 +18,10 @@
import { DeleteIcon } from "@components/Icons";
import { classes } from "@utils/misc";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { Tooltip } from "@webpack/common";
const iconClasses = findByPropsLazy("button", "wrapper", "disabled", "separator");
const iconClasses = findByProps("button", "wrapper", "disabled", "separator");
export function DeleteButton({ onClick }: { onClick(): void; }) {
return (

View file

@ -18,8 +18,7 @@
import { openUserProfile } from "@utils/discord";
import { classes } from "@utils/misc";
import { LazyComponent } from "@utils/react";
import { filters, findBulk } from "@webpack";
import { findByProps } from "@webpack";
import { Alerts, Parser, Timestamp, useState } from "@webpack/common";
import { Auth, getToken } from "../auth";
@ -31,161 +30,150 @@ import { openBlockModal } from "./BlockedUserModal";
import { BlockButton, DeleteButton, ReportButton } from "./MessageButton";
import ReviewBadge from "./ReviewBadge";
export default LazyComponent(() => {
// this is terrible, blame mantika
const p = filters.byProps;
const [
{ cozyMessage, buttons, message, buttonsInner, groupStart },
{ container, isHeader },
{ avatar, clickable, username, wrapper, cozy },
buttonClasses,
botTag
] = findBulk(
p("cozyMessage"),
p("container", "isHeader"),
p("avatar", "zalgo"),
p("button", "wrapper", "selected"),
p("botTag", "botTagRegular")
);
const { cozyMessage, message, groupStart, buttons, buttonsInner } = findByProps("cozyMessage");
const { container, isHeader } = findByProps("container", "isHeader");
const { wrapper, cozy, avatar, clickable, username } = findByProps("avatar", "zalgo");
const buttonClasses = findByProps("button", "wrapper", "selected");
const botTag = findByProps("botTag", "botTagRegular");
const dateFormat = new Intl.DateTimeFormat();
const dateFormat = new Intl.DateTimeFormat();
return function ReviewComponent({ review, refetch, profileId }: { review: Review; refetch(): void; profileId: string; }) {
const [showAll, setShowAll] = useState(false);
export default function ReviewComponent({ review, refetch, profileId }: { review: Review; refetch(): void; profileId: string; }) {
const [showAll, setShowAll] = useState(false);
function openModal() {
openUserProfile(review.sender.discordID);
}
function openModal() {
openUserProfile(review.sender.discordID);
}
function delReview() {
Alerts.show({
title: "Are you sure?",
body: "Do you really want to delete this review?",
confirmText: "Delete",
cancelText: "Nevermind",
onConfirm: async () => {
if (!(await getToken())) {
return showToast("You must be logged in to delete reviews.");
} else {
deleteReview(review.id).then(res => {
if (res) {
refetch();
}
});
}
function delReview() {
Alerts.show({
title: "Are you sure?",
body: "Do you really want to delete this review?",
confirmText: "Delete",
cancelText: "Nevermind",
onConfirm: async () => {
if (!(await getToken())) {
return showToast("You must be logged in to delete reviews.");
} else {
deleteReview(review.id).then(res => {
if (res) {
refetch();
}
});
}
});
}
}
});
}
function reportRev() {
Alerts.show({
title: "Are you sure?",
body: "Do you really you want to report this review?",
confirmText: "Report",
cancelText: "Nevermind",
// confirmColor: "red", this just adds a class name and breaks the submit button guh
onConfirm: async () => {
if (!(await getToken())) {
return showToast("You must be logged in to report reviews.");
} else {
reportReview(review.id);
}
function reportRev() {
Alerts.show({
title: "Are you sure?",
body: "Do you really you want to report this review?",
confirmText: "Report",
cancelText: "Nevermind",
// confirmColor: "red", this just adds a class name and breaks the submit button guh
onConfirm: async () => {
if (!(await getToken())) {
return showToast("You must be logged in to report reviews.");
} else {
reportReview(review.id);
}
});
}
}
});
}
const isAuthorBlocked = Auth?.user?.blockedUsers?.includes(review.sender.discordID) ?? false;
const isAuthorBlocked = Auth?.user?.blockedUsers?.includes(review.sender.discordID) ?? false;
function blockReviewSender() {
if (isAuthorBlocked)
return unblockUser(review.sender.discordID);
function blockReviewSender() {
if (isAuthorBlocked)
return unblockUser(review.sender.discordID);
Alerts.show({
title: "Are you sure?",
body: "Do you really you want to block this user? They will be unable to leave further reviews on your profile. You can unblock users in the plugin settings.",
confirmText: "Block",
cancelText: "Nevermind",
// confirmColor: "red", this just adds a class name and breaks the submit button guh
onConfirm: async () => {
if (!(await getToken())) {
return showToast("You must be logged in to block users.");
} else {
blockUser(review.sender.discordID);
}
Alerts.show({
title: "Are you sure?",
body: "Do you really you want to block this user? They will be unable to leave further reviews on your profile. You can unblock users in the plugin settings.",
confirmText: "Block",
cancelText: "Nevermind",
// confirmColor: "red", this just adds a class name and breaks the submit button guh
onConfirm: async () => {
if (!(await getToken())) {
return showToast("You must be logged in to block users.");
} else {
blockUser(review.sender.discordID);
}
});
}
}
});
}
return (
<div className={classes(cl("review"), cozyMessage, wrapper, message, groupStart, cozy)} style={
{
marginLeft: "0px",
paddingLeft: "52px", // wth is this
// nobody knows anymore
}
}>
return (
<div className={classes(cl("review"), cozyMessage, wrapper, message, groupStart, cozy)} style={
{
marginLeft: "0px",
paddingLeft: "52px", // wth is this
// nobody knows anymore
}
}>
<img
className={classes(avatar, clickable)}
onClick={openModal}
src={review.sender.profilePhoto || "/assets/1f0bfc0865d324c2587920a7d80c609b.png?size=128"}
style={{ left: "0px", zIndex: 0 }}
/>
<div style={{ display: "inline-flex", justifyContent: "center", alignItems: "center" }}>
<img
className={classes(avatar, clickable)}
onClick={openModal}
src={review.sender.profilePhoto || "/assets/1f0bfc0865d324c2587920a7d80c609b.png?size=128"}
style={{ left: "0px", zIndex: 0 }}
/>
<div style={{ display: "inline-flex", justifyContent: "center", alignItems: "center" }}>
<span
className={classes(clickable, username)}
style={{ color: "var(--channels-default)", fontSize: "14px" }}
onClick={() => openModal()}
>
{review.sender.username}
</span>
{review.type === ReviewType.System && (
<span
className={classes(clickable, username)}
style={{ color: "var(--channels-default)", fontSize: "14px" }}
onClick={() => openModal()}
>
{review.sender.username}
</span>
{review.type === ReviewType.System && (
<span
className={classes(botTag.botTagVerified, botTag.botTagRegular, botTag.botTag, botTag.px, botTag.rem)}
style={{ marginLeft: "4px" }}>
<span className={botTag.botText}>
System
</span>
className={classes(botTag.botTagVerified, botTag.botTagRegular, botTag.botTag, botTag.px, botTag.rem)}
style={{ marginLeft: "4px" }}>
<span className={botTag.botText}>
System
</span>
)}
</div>
{isAuthorBlocked && (
<ReviewBadge
name="You have blocked this user"
description="You have blocked this user"
icon="/assets/aaee57e0090991557b66.svg"
type={0}
onClick={() => openBlockModal()}
/>
)}
{review.sender.badges.map(badge => <ReviewBadge {...badge} />)}
{
!settings.store.hideTimestamps && review.type !== ReviewType.System && (
<Timestamp timestamp={new Date(review.timestamp * 1000)} >
{dateFormat.format(review.timestamp * 1000)}
</Timestamp>)
}
<div className={cl("review-comment")}>
{(review.comment.length > 200 && !showAll)
? [Parser.parseGuildEventDescription(review.comment.substring(0, 200)), "...", <br />, (<a onClick={() => setShowAll(true)}>Read more</a>)]
: Parser.parseGuildEventDescription(review.comment)}
</div>
{review.id !== 0 && (
<div className={classes(container, isHeader, buttons)} style={{
padding: "0px",
}}>
<div className={classes(buttonClasses.wrapper, buttonsInner)} >
{canReportReview(review) && <ReportButton onClick={reportRev} />}
{canBlockReviewAuthor(profileId, review) && <BlockButton isBlocked={isAuthorBlocked} onClick={blockReviewSender} />}
{canDeleteReview(profileId, review) && <DeleteButton onClick={delReview} />}
</div>
</div>
</span>
)}
</div>
);
};
});
{isAuthorBlocked && (
<ReviewBadge
name="You have blocked this user"
description="You have blocked this user"
icon="/assets/aaee57e0090991557b66.svg"
type={0}
onClick={() => openBlockModal()}
/>
)}
{review.sender.badges.map(badge => <ReviewBadge {...badge} />)}
{
!settings.store.hideTimestamps && review.type !== ReviewType.System && (
<Timestamp timestamp={new Date(review.timestamp * 1000)} >
{dateFormat.format(review.timestamp * 1000)}
</Timestamp>)
}
<div className={cl("review-comment")}>
{(review.comment.length > 200 && !showAll)
? [Parser.parseGuildEventDescription(review.comment.substring(0, 200)), "...", <br />, (<a onClick={() => setShowAll(true)}>Read more</a>)]
: Parser.parseGuildEventDescription(review.comment)}
</div>
{review.id !== 0 && (
<div className={classes(container, isHeader, buttons)} style={{
padding: "0px",
}}>
<div className={classes(buttonClasses.wrapper, buttonsInner)} >
{canReportReview(review) && <ReportButton onClick={reportRev} />}
{canBlockReviewAuthor(profileId, review) && <BlockButton isBlocked={isAuthorBlocked} onClick={blockReviewSender} />}
{canDeleteReview(profileId, review) && <DeleteButton onClick={delReview} />}
</div>
</div>
)}
</div>
);
}

View file

@ -17,7 +17,7 @@
*/
import { useAwaiter, useForceUpdater } from "@utils/react";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { findByProps, findComponentByCode } from "@webpack";
import { Forms, React, RelationshipStore, useRef, UserStore } from "@webpack/common";
import { Auth, authorize } from "../auth";
@ -28,11 +28,11 @@ import { cl, showToast } from "../utils";
import ReviewComponent from "./ReviewComponent";
const { Editor, Transforms } = findByPropsLazy("Editor", "Transforms");
const { ChatInputTypes } = findByPropsLazy("ChatInputTypes");
const { Editor, Transforms } = findByProps("Editor", "Transforms");
const { ChatInputTypes } = findByProps("ChatInputTypes");
const InputComponent = findComponentByCodeLazy("default.CHANNEL_TEXT_AREA", "input");
const { createChannelRecordFromServer } = findByPropsLazy("createChannelRecordFromServer");
const InputComponent = findComponentByCode("default.CHANNEL_TEXT_AREA", "input");
const { createChannelRecordFromServer } = findByProps("createChannelRecordFromServer");
interface UserProps {
discordId: string;

View file

@ -20,12 +20,12 @@ import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/Co
import { ReplyIcon } from "@components/Icons";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { ChannelStore, i18n, Menu, PermissionsBits, PermissionStore, SelectedChannelStore } from "@webpack/common";
import { Message } from "discord-types/general";
const messageUtils = findByPropsLazy("replyToMessage");
const messageUtils = findByProps("replyToMessage");
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, { message }: { message: Message; }) => {
// make sure the message is in the selected channel

View file

@ -11,12 +11,12 @@ import { openImageModal, openUserProfile } from "@utils/discord";
import { classes } from "@utils/misc";
import { ModalRoot, ModalSize, openModal } from "@utils/modal";
import { useAwaiter } from "@utils/react";
import { findByPropsLazy, findExportedComponentLazy } from "@webpack";
import { findByProps,findExportedComponent } from "@webpack";
import { FluxDispatcher, Forms, GuildChannelStore, GuildMemberStore, GuildStore, IconUtils, Parser, PresenceStore, RelationshipStore, ScrollerThin, SnowflakeUtils, TabBar, Timestamp, useEffect, UserStore, UserUtils, useState, useStateFromStores } from "@webpack/common";
import { Guild, User } from "discord-types/general";
const IconClasses = findByPropsLazy("icon", "acronym", "childWrapper");
const FriendRow = findExportedComponentLazy("FriendRow");
const IconClasses = findByProps("icon", "acronym", "childWrapper");
const FriendRow = findExportedComponent("FriendRow");
const cl = classNameFactory("vc-gp-");

View file

@ -4,7 +4,7 @@ import React from "react";
const handleClick = async () =>
console.log((await import("@webpack/common")).Clipboard.copy("\u200b"));
export const Example: React.FC<{
export const Example: React.ComponentType<{
real: boolean,
shigged?: number,
}> = ({ real, shigged }) => <>

View file

@ -16,11 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { findComponentByCodeLazy, findLazy } from "@webpack";
import { find, findComponentByCode } from "@webpack";
import { i18n, useToken } from "@webpack/common";
const ColorMap = findLazy(m => m.colors?.INTERACTIVE_MUTED?.css);
const VerifiedIconComponent = findComponentByCodeLazy(".CONNECTIONS_ROLE_OFFICIAL_ICON_TOOLTIP");
const ColorMap = find(m => m.colors?.INTERACTIVE_MUTED?.css);
const VerifiedIconComponent = findComponentByCode(".CONNECTIONS_ROLE_OFFICIAL_ICON_TOOLTIP");
export function VerifiedIcon() {
const color = useToken(ColorMap.colors.INTERACTIVE_MUTED).hex();

View file

@ -25,17 +25,17 @@ import { CopyIcon, LinkIcon } from "@components/Icons";
import { Devs } from "@utils/constants";
import { copyWithToast } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
import { findByCode, findByProps, findComponentByCode, findStore } from "@webpack";
import { Text, Tooltip, UserProfileStore } from "@webpack/common";
import { User } from "discord-types/general";
import { VerifiedIcon } from "./VerifiedIcon";
const Section = findComponentByCodeLazy(".lastSection", "children:");
const ThemeStore = findStoreLazy("ThemeStore");
const platformHooks: { useLegacyPlatformType(platform: string): string; } = findByPropsLazy("useLegacyPlatformType");
const platforms: { get(type: string): ConnectionPlatform; } = findByPropsLazy("isSupported", "getByUrl");
const getProfileThemeProps = findByCodeLazy(".getPreviewThemeColors", "primaryColor:");
const Section = findComponentByCode(".lastSection", "children:");
const ThemeStore = findStore("ThemeStore");
const platformHooks: { useLegacyPlatformType(platform: string): string; } = findByProps("useLegacyPlatformType");
const platforms: { get(type: string): ConnectionPlatform; } = findByProps("isSupported", "getByUrl");
const getProfileThemeProps = findByCode(".getPreviewThemeColors", "primaryColor:");
const enum Spacing {
COMPACT,

View file

@ -19,7 +19,7 @@
import { Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { formatDuration } from "@utils/text";
import { findByPropsLazy, findComponentByCodeLazy, findComponentLazy } from "@webpack";
import { findByProps,findComponent, findComponentByCode } from "@webpack";
import { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, Parser, PermissionsBits, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from "@webpack/common";
import type { Channel } from "discord-types/general";
@ -78,10 +78,10 @@ const enum ChannelFlags {
}
const ChatScrollClasses = findByPropsLazy("auto", "content", "scrollerBase");
const ChatClasses = findByPropsLazy("chat", "content", "noChat", "chatContent");
const ChannelBeginHeader = findComponentByCodeLazy(".Messages.ROLE_REQUIRED_SINGLE_USER_MESSAGE");
const TagComponent = findComponentLazy(m => {
const ChatScrollClasses = findByProps("auto", "content", "scrollerBase");
const ChatClasses = findByProps("chat", "content", "noChat", "chatContent");
const ChannelBeginHeader = findComponentByCode(".Messages.ROLE_REQUIRED_SINGLE_USER_MESSAGE");
const TagComponent = findComponent(m => {
if (typeof m !== "function") return false;
const code = Function.prototype.toString.call(m);
@ -89,8 +89,8 @@ const TagComponent = findComponentLazy(m => {
return code.includes(".Messages.FORUM_TAG_A11Y_FILTER_BY_TAG") && !code.includes("increasedActivityPill");
});
const EmojiParser = findByPropsLazy("convertSurrogateToName");
const EmojiUtils = findByPropsLazy("getURL", "getEmojiColors");
const EmojiParser = findByProps("convertSurrogateToName");
const EmojiUtils = findByProps("getURL", "getEmojiColors");
const ChannelTypesToChannelNames = {
[ChannelTypes.GUILD_TEXT]: "text",

View file

@ -23,13 +23,13 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { canonicalizeMatch } from "@utils/patches";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { ChannelStore, PermissionsBits, PermissionStore, Tooltip } from "@webpack/common";
import type { Channel, Role } from "discord-types/general";
import HiddenChannelLockScreen from "./components/HiddenChannelLockScreen";
const ChannelListClasses = findByPropsLazy("modeMuted", "modeSelected", "unread", "icon");
const ChannelListClasses = findByProps("modeMuted", "modeSelected", "unread", "icon");
const enum ShowMode {
LockIcon,

View file

@ -17,7 +17,7 @@
*/
import { Settings } from "@api/Settings";
import { findByProps, proxyLazyWebpack } from "@webpack";
import { findByProps, webpackDependantLazy } from "@webpack";
import { Flux, FluxDispatcher } from "@webpack/common";
export interface Track {
@ -64,14 +64,14 @@ interface Device {
type Repeat = "off" | "track" | "context";
const SpotifySocket = findByProps("getActiveSocketAndDevice");
const SpotifyUtils = findByProps("SpotifyAPI");
// Don't wanna run before Flux and Dispatcher are ready!
export const SpotifyStore = proxyLazyWebpack(() => {
export const SpotifyStore = webpackDependantLazy(() => {
// For some reason ts hates extends Flux.Store
const { Store } = Flux;
const SpotifySocket = findByProps("getActiveSocketAndDevice");
const SpotifyUtils = findByProps("SpotifyAPI");
const API_BASE = "https://api.spotify.com/v1/me/player";
class SpotifyStore extends Store {

View file

@ -19,7 +19,7 @@
import { ApplicationCommandInputType, sendBotMessage } from "@api/Commands";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { FluxDispatcher, MessageActions } from "@webpack/common";
interface Album {
@ -52,8 +52,8 @@ interface Track {
name: string;
}
const Spotify = findByPropsLazy("getPlayerState");
const PendingReplyStore = findByPropsLazy("getPendingReply");
const Spotify = findByProps("getPlayerState");
const PendingReplyStore = findByProps("getPendingReply");
function sendMessage(channelId, message) {
message = {

View file

@ -18,7 +18,7 @@
import ErrorBoundary from "@components/ErrorBoundary";
import { Flex } from "@components/Flex";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { Forms, React } from "@webpack/common";
interface AppStartPerformance {
@ -45,7 +45,7 @@ interface Log {
delta?: number;
}
const AppStartPerformance = findByPropsLazy("markWithDelta", "markAndLog", "markAt") as AppStartPerformance;
const AppStartPerformance = findByProps("markWithDelta", "markAndLog", "markAt") as AppStartPerformance;
interface TimerItemProps extends Log {
instance: {

View file

@ -22,16 +22,16 @@ import { definePluginSettings, Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findComponentByCodeLazy, findExportedComponentLazy, findStoreLazy } from "@webpack";
import { findComponentByCode, findExportedComponent, findStore } from "@webpack";
import { ChannelStore, GuildMemberStore, i18n, RelationshipStore, SelectedChannelStore, Tooltip, UserStore, useStateFromStores } from "@webpack/common";
import { buildSeveralUsers } from "../typingTweaks";
const ThreeDots = findExportedComponentLazy("Dots", "AnimatedDots");
const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers");
const ThreeDots = findExportedComponent("Dots", "AnimatedDots");
const UserSummaryItem = findComponentByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers");
const TypingStore = findStoreLazy("TypingStore");
const UserGuildSettingsStore = findStoreLazy("UserGuildSettingsStore");
const TypingStore = findStore("TypingStore");
const UserGuildSettingsStore = findStore("UserGuildSettingsStore");
const enum IndicatorMode {
Dots = 1 << 0,

View file

@ -18,12 +18,12 @@
import "./VoiceChannelSection.css";
import { findByCodeLazy, findByPropsLazy } from "@webpack";
import { findByCode,findByProps } from "@webpack";
import { Button, Forms, PermissionStore, Toasts } from "@webpack/common";
import { Channel } from "discord-types/general";
const ChannelActions = findByPropsLazy("selectChannel", "selectVoiceChannel");
const UserPopoutSection = findByCodeLazy(".lastSection", "children:");
const ChannelActions = findByProps("selectChannel", "selectVoiceChannel");
const UserPopoutSection = findByCode(".lastSection", "children:");
const CONNECT = 1n << 20n;

View file

@ -20,13 +20,13 @@ import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findStoreLazy } from "@webpack";
import { findStore } from "@webpack";
import { ChannelStore, GuildStore, UserStore } from "@webpack/common";
import { User } from "discord-types/general";
import { VoiceChannelSection } from "./components/VoiceChannelSection";
const VoiceStateStore = findStoreLazy("VoiceStateStore");
const VoiceStateStore = findStore("VoiceStateStore");
const settings = definePluginSettings({
showInUserProfileModal: {

View file

@ -23,7 +23,7 @@ import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins";
import { wordsToTitle } from "@utils/text";
import definePlugin, { OptionType, PluginOptionsItem } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { Button, ChannelStore, Forms, GuildMemberStore, SelectedChannelStore, SelectedGuildStore, useMemo, UserStore } from "@webpack/common";
interface VoiceState {
@ -36,7 +36,7 @@ interface VoiceState {
selfMute: boolean;
}
const VoiceStateStore = findByPropsLazy("getVoiceStatesForChannel", "getCurrentClientVoiceChannelId");
const VoiceStateStore = findByProps("getVoiceStatesForChannel", "getCurrentClientVoiceChannelId");
// Mute/Deaf for other people than you is commented out, because otherwise someone can spam it and it will be annoying
// Filtering out events is not as simple as just dropping duplicates, as otherwise mute, unmute, mute would

View file

@ -23,11 +23,11 @@ import { Settings, useSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findExportedComponentLazy } from "@webpack";
import { findExportedComponent } from "@webpack";
import { Menu, Popout, useState } from "@webpack/common";
import type { ReactNode } from "react";
const HeaderBarIcon = findExportedComponentLazy("Icon", "Divider");
const HeaderBarIcon = findExportedComponent("Icon", "Divider");
function VencordPopout(onClose: () => void) {
const { useQuickCss } = useSettings(["useQuickCss"]);

View file

@ -17,7 +17,7 @@
*/
import { useTimer } from "@utils/react";
import { findComponentByCodeLazy } from "@webpack";
import { findComponentByCode } from "@webpack";
import { cl } from "./utils";
@ -25,7 +25,7 @@ interface VoiceMessageProps {
src: string;
waveform: string;
}
const VoiceMessage = findComponentByCodeLazy<VoiceMessageProps>("waveform:", "onVolumeChange");
const VoiceMessage = findComponentByCode<VoiceMessageProps>("waveform:", "onVolumeChange");
export type VoicePreviewOptions = {
src?: string;

View file

@ -27,7 +27,7 @@ import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModa
import { useAwaiter } from "@utils/react";
import definePlugin from "@utils/types";
import { chooseFile } from "@utils/web";
import { findByPropsLazy, findStoreLazy } from "@webpack";
import { findByProps, findStore } from "@webpack";
import { Button, Card, FluxDispatcher, Forms, lodash, Menu, MessageActions, PermissionsBits, PermissionStore, RestAPI, SelectedChannelStore, showToast, SnowflakeUtils, Toasts, useEffect, useState } from "@webpack/common";
import { ComponentType } from "react";
@ -37,9 +37,9 @@ import { cl } from "./utils";
import { VoicePreview } from "./VoicePreview";
import { VoiceRecorderWeb } from "./WebRecorder";
const CloudUtils = findByPropsLazy("CloudUpload");
const PendingReplyStore = findStoreLazy("PendingReplyStore");
const OptionClasses = findByPropsLazy("optionName", "optionIcon", "optionLabel");
const CloudUtils = findByProps("CloudUpload");
const PendingReplyStore = findStore("PendingReplyStore");
const OptionClasses = findByProps("optionName", "optionIcon", "optionLabel");
export type VoiceRecorder = ComponentType<{
setAudioBlob(blob: Blob): void;

View file

@ -20,10 +20,10 @@ import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { saveFile } from "@utils/web";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { Clipboard, ComponentDispatch } from "@webpack/common";
const ctxMenuCallbacks = findByPropsLazy("contextMenuCallbackNative");
const ctxMenuCallbacks = findByProps("contextMenuCallbackNative");
async function fetchImage(url: string) {
const res = await fetch(url);

View file

@ -18,10 +18,10 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { ComponentDispatch, FluxDispatcher, NavigationRouter, SelectedGuildStore, SettingsRouter } from "@webpack/common";
const KeyBinds = findByPropsLazy("JUMP_TO_GUILD", "SERVER_NEXT");
const KeyBinds = findByProps("JUMP_TO_GUILD", "SERVER_NEXT");
export default definePlugin({
name: "WebKeybinds",

View file

@ -22,14 +22,15 @@ import { sleep } from "@utils/misc";
import { Queue } from "@utils/Queue";
import { useForceUpdater } from "@utils/react";
import definePlugin from "@utils/types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { findByProps, findComponentByCode } from "@webpack";
import { ChannelStore, FluxDispatcher, React, RestAPI, Tooltip } from "@webpack/common";
import { CustomEmoji } from "@webpack/types";
import { Message, ReactionEmoji, User } from "discord-types/general";
const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers");
const AvatarStyles = findByPropsLazy("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar");
const UserSummaryItem = findComponentByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers");
const AvatarStyles = findByProps("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar");
let Scroll: any = null;
const queue = new Queue();
let reactions: Record<string, ReactionCacheEntry>;

View file

@ -9,7 +9,7 @@ import { makeRange } from "@components/PluginSettings/components";
import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType, PluginNative } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { findByProps } from "@webpack";
import { ChannelStore, GuildStore, UserStore } from "@webpack/common";
import type { Channel, Embed, GuildMember, MessageAttachment, User } from "discord-types/general";
@ -71,7 +71,7 @@ interface Call {
ringing: string[];
}
const MuteStore = findByPropsLazy("isSuppressEveryoneEnabled");
const MuteStore = findByProps("isSuppressEveryoneEnabled");
const XSLog = new Logger("XSOverlay");
const settings = definePluginSettings({

View file

@ -20,7 +20,7 @@ import { MessageObject } from "@api/MessageEvents";
import { ChannelStore, ComponentDispatch, FluxDispatcher, GuildStore, InviteActions, MaskedLink, MessageActions, ModalImageClasses, PrivateChannelsStore, RestAPI, SelectedChannelStore, SelectedGuildStore, UserProfileActions, UserProfileStore, UserSettingsActionCreators, UserUtils } from "@webpack/common";
import { Guild, Message, User } from "discord-types/general";
import { ImageModal, ModalRoot, ModalSize, openModal } from "./modal";
import { ImageModal, ImageModalProps, ModalRoot, ModalSize, openModal } from "./modal";
/**
* Open the invite modal
@ -108,7 +108,7 @@ export function sendMessage(
return MessageActions.sendMessage(channelId, messageData, waitForChannelReady, extra);
}
export function openImageModal(url: string, props?: Partial<React.ComponentProps<ImageModal>>): string {
export function openImageModal(url: string, props?: Partial<ImageModalProps>): string {
return openModal(modalProps => (
<ModalRoot
{...modalProps}

View file

@ -30,6 +30,7 @@ export * from "./misc";
export * from "./modal";
export * from "./onlyOnce";
export * from "./patches";
export * from "./proxyInner";
export * from "./Queue";
export * from "./react";
export * from "./text";

View file

@ -1,20 +1,8 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
export function makeLazy<T>(factory: () => T, attempts = 5): () => T {
let tries = 0;
@ -22,8 +10,9 @@ export function makeLazy<T>(factory: () => T, attempts = 5): () => T {
return () => {
if (!cache && attempts > tries++) {
cache = factory();
if (!cache && attempts === tries)
console.error("Lazy factory failed:", factory);
if (!cache && attempts === tries) {
console.error(`Lazy factory failed:\n${factory}`);
}
}
return cache;
};
@ -33,94 +22,81 @@ export function makeLazy<T>(factory: () => T, attempts = 5): () => T {
// will always return the function default for them.
const unconfigurable = ["arguments", "caller", "prototype"];
const handler: ProxyHandler<any> = {};
const handler: ProxyHandler<any> = {
...Object.fromEntries(Object.getOwnPropertyNames(Reflect).map(propName =>
[propName, (target: any, ...args: any[]) => Reflect[propName](target[proxyLazyGet](), ...args)]
)),
ownKeys: target => {
const keys = Reflect.ownKeys(target[proxyLazyGet]());
for (const key of unconfigurable) {
if (!keys.includes(key)) keys.push(key);
}
return keys;
},
getOwnPropertyDescriptor: (target, p) => {
if (typeof p === "string" && unconfigurable.includes(p))
return Reflect.getOwnPropertyDescriptor(target, p);
const kGET = Symbol.for("vencord.lazy.get");
const kCACHE = Symbol.for("vencord.lazy.cached");
for (const method of [
"apply",
"construct",
"defineProperty",
"deleteProperty",
"getOwnPropertyDescriptor",
"getPrototypeOf",
"has",
"isExtensible",
"ownKeys",
"preventExtensions",
"set",
"setPrototypeOf"
]) {
handler[method] =
(target: any, ...args: any[]) => Reflect[method](target[kGET](), ...args);
}
handler.ownKeys = target => {
const v = target[kGET]();
const keys = Reflect.ownKeys(v);
for (const key of unconfigurable) {
if (!keys.includes(key)) keys.push(key);
const descriptor = Reflect.getOwnPropertyDescriptor(target[proxyLazyGet](), p);
if (descriptor) Object.defineProperty(target, p, descriptor);
return descriptor;
}
return keys;
};
handler.getOwnPropertyDescriptor = (target, p) => {
if (typeof p === "string" && unconfigurable.includes(p))
return Reflect.getOwnPropertyDescriptor(target, p);
const descriptor = Reflect.getOwnPropertyDescriptor(target[kGET](), p);
if (descriptor) Object.defineProperty(target, p, descriptor);
return descriptor;
};
const proxyLazyGet = Symbol.for("vencord.lazy.get");
const proxyLazyCache = Symbol.for("vencord.lazy.cached");
/**
* Wraps the result of {@link makeLazy} in a Proxy you can consume as if it wasn't lazy.
* On first property access, the lazy is evaluated
* @param factory lazy factory
* @param attempts how many times to try to evaluate the lazy before giving up
* @returns Proxy
*
* Note that the example below exists already as an api, see {@link findByPropsLazy}
* @example const mod = proxyLazy(() => findByProps("blah")); console.log(mod.blah);
* Wraps the result of factory in a Proxy you can consume as if it wasn't lazy.
* On first property access, the factory is evaluated
* @param factory Factory returning the result
* @param attempts How many times to try to evaluate the factory before giving up
* @returns Result of factory function
*/
export function proxyLazy<T>(factory: () => T, attempts = 5, isChild = false): T {
let isSameTick = true;
if (!isChild)
setTimeout(() => isSameTick = false, 0);
export function proxyLazy<T = any>(factory: () => T, attempts = 5, isChild = false): T {
const get = makeLazy(factory, attempts);
let tries = 0;
let isSameTick = true;
if (!isChild) setTimeout(() => isSameTick = false, 0);
let failed = false;
const proxyDummy = Object.assign(function () { }, {
[kCACHE]: void 0 as T | undefined,
[kGET]() {
if (!proxyDummy[kCACHE] && attempts > tries++) {
proxyDummy[kCACHE] = factory();
if (!proxyDummy[kCACHE] && attempts === tries)
console.error("Lazy factory failed:", factory);
[proxyLazyGet]() {
if (!proxyDummy[proxyLazyCache] && !failed) {
proxyDummy[proxyLazyCache] = get();
if (!proxyDummy[proxyLazyCache]) {
failed = true;
throw new Error(`proxyLazy factory failed:\n${factory}`);
}
}
return proxyDummy[kCACHE];
}
return proxyDummy[proxyLazyCache];
},
[proxyLazyCache]: void 0 as T | undefined
});
return new Proxy(proxyDummy, {
...handler,
get(target, p, receiver) {
// if we're still in the same tick, it means the lazy was immediately used.
// If we're still in the same tick, it means the lazy was immediately used.
// thus, we lazy proxy the get access to make things like destructuring work as expected
// meow here will also be a lazy
// `const { meow } = findByPropsLazy("meow");`
if (!isChild && isSameTick)
if (!isChild && isSameTick) {
return proxyLazy(
() => Reflect.get(target[kGET](), p, receiver),
() => Reflect.get(target[proxyLazyGet](), p, receiver),
attempts,
true
);
const lazyTarget = target[kGET]();
}
const lazyTarget = target[proxyLazyGet]();
if (typeof lazyTarget === "object" || typeof lazyTarget === "function") {
return Reflect.get(lazyTarget, p, receiver);
}
throw new Error("proxyLazy called on a primitive value");
}
}) as any;
}) as T;
}

View file

@ -8,22 +8,32 @@ import { ComponentType } from "react";
import { makeLazy } from "./lazy";
const NoopComponent = () => null;
export const NoopComponent = () => null;
/**
* A lazy component. The factory method is called on first render.
* @param factory Function returning a Component
* @param factory Function returning a component
* @param attempts How many times to try to get the component before giving up
* @returns Result of factory function
*/
export function LazyComponent<T extends object = any>(factory: () => React.ComponentType<T>, attempts = 5) {
const get = makeLazy(factory, attempts);
let failed = false;
const LazyComponent = (props: T) => {
const Component = get() ?? NoopComponent;
const Component = get() ?? (() => {
if (!failed) {
failed = true;
console.error(`LazyComponent factory failed:\n${factory}`);
}
return NoopComponent;
})();
return <Component {...props} />;
};
LazyComponent.$$vencordInternal = get;
LazyComponent.$$vencordGetter = get;
return LazyComponent as ComponentType<T>;
}

View file

@ -16,10 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { findByPropsLazy, findExportedComponentLazy } from "@webpack";
import { filters, find, findByProps, findExportedComponent } from "@webpack";
import type { ComponentType, PropsWithChildren, ReactNode, Ref } from "react";
import { LazyComponent } from "./react";
export const enum ModalSize {
SMALL = "small",
@ -49,7 +48,7 @@ export interface ModalOptions {
type RenderFunction = (props: ModalProps) => ReactNode;
export const Modals = findByPropsLazy("ModalRoot", "ModalCloseButton") as {
type Modals = {
ModalRoot: ComponentType<PropsWithChildren<{
transitionState: ModalTransitionState;
size?: ModalSize;
@ -101,7 +100,19 @@ export const Modals = findByPropsLazy("ModalRoot", "ModalCloseButton") as {
}>;
};
export type ImageModal = ComponentType<{
export let ModalRoot: Modals["ModalRoot"];
export let ModalHeader: Modals["ModalHeader"];
export let ModalContent: Modals["ModalContent"];
export let ModalFooter: Modals["ModalFooter"];
export let ModalCloseButton: Modals["ModalCloseButton"];
export const Modals = find<Modals>(filters.byProps("ModalRoot", "ModalCloseButton"), m => {
({ ModalRoot, ModalHeader, ModalContent, ModalFooter, ModalCloseButton } = m);
return m;
});
export type ImageModalProps = {
className?: string;
src: string;
placeholder: string;
@ -116,17 +127,11 @@ export type ImageModal = ComponentType<{
shouldAnimate?: boolean;
onClose?(): void;
shouldHideMediaOptions?: boolean;
}>;
};
export const ImageModal = findExportedComponentLazy("ImageModal") as ImageModal;
export const ImageModal = findExportedComponent<ImageModalProps>("ImageModal");
export const ModalRoot = LazyComponent(() => Modals.ModalRoot);
export const ModalHeader = LazyComponent(() => Modals.ModalHeader);
export const ModalContent = LazyComponent(() => Modals.ModalContent);
export const ModalFooter = LazyComponent(() => Modals.ModalFooter);
export const ModalCloseButton = LazyComponent(() => Modals.ModalCloseButton);
const ModalAPI = findByPropsLazy("openModalLazy");
const ModalAPI = findByProps("openModalLazy");
/**
* Wait for the render promise to resolve, then open a modal with it.

91
src/utils/proxyInner.ts Normal file
View file

@ -0,0 +1,91 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
export const proxyInnerGet = Symbol.for("vencord.proxyInner.get");
export const proxyInnerValue = Symbol.for("vencord.proxyInner.innerValue");
// Proxies demand that these properties be unmodified, so proxyInner
// will always return the function default for them.
const unconfigurable = ["arguments", "caller", "prototype"];
const handler: ProxyHandler<any> = {
...Object.fromEntries(Object.getOwnPropertyNames(Reflect).map(propName =>
[propName, (target: any, ...args: any[]) => Reflect[propName](target[proxyInnerGet](), ...args)]
)),
ownKeys: target => {
const keys = Reflect.ownKeys(target[proxyInnerGet]());
for (const key of unconfigurable) {
if (!keys.includes(key)) keys.push(key);
}
return keys;
},
getOwnPropertyDescriptor: (target, p) => {
if (typeof p === "string" && unconfigurable.includes(p))
return Reflect.getOwnPropertyDescriptor(target, p);
const descriptor = Reflect.getOwnPropertyDescriptor(target[proxyInnerGet](), p);
if (descriptor) Object.defineProperty(target, p, descriptor);
return descriptor;
}
};
/**
* A proxy which has an inner value that can be set later.
* When a property is accessed, the proxy looks for the property value in its inner value, and errors if it's not set.
* @param err The error to throw when the inner value is not set
* @returns A proxy which will act like the inner value when accessed
*/
export function proxyInner<T = any>(err = new Error("Proxy inner value is undefined, setInnerValue was never called."), isChild = false): [proxy: T, setInnerValue: (innerValue: T) => void] {
let isSameTick = true;
if (!isChild) setTimeout(() => isSameTick = false, 0);
const proxyDummy = Object.assign(function () { }, {
[proxyInnerGet]: function () {
if (proxyDummy[proxyInnerValue] == null) {
throw err;
}
return proxyDummy[proxyInnerValue];
},
[proxyInnerValue]: void 0 as T | undefined
});
const recursiveSetInnerValues = [] as Array<(innerValue: T) => void>;
function setInnerValue(innerValue: T) {
proxyDummy[proxyInnerValue] = innerValue;
recursiveSetInnerValues.forEach(setInnerValue => setInnerValue(innerValue));
}
return [new Proxy(proxyDummy, {
...handler,
get(target, p, receiver) {
if (p === proxyInnerValue) return target[proxyInnerValue];
if (p === proxyInnerGet) return target[proxyInnerGet];
// If we're still in the same tick, it means the proxy was immediately used.
// thus, we proxy the get access to make things like destructuring work as expected
// meow here will also be a proxy
// `const { meow } = findByProps("meow");`
if (!isChild && isSameTick) {
const [recursiveProxy, recursiveSetInnerValue] = proxyInner(err, true);
recursiveSetInnerValues.push((innerValue: T) => {
recursiveSetInnerValue(Reflect.get(innerValue as object, p, receiver));
});
return recursiveProxy;
}
const innerTarget = target[proxyInnerGet]();
if (typeof innerTarget === "object" || typeof innerTarget === "function") {
return Reflect.get(innerTarget, p, receiver);
}
throw new Error("proxyInner called on a primitive value");
}
}) as T, setInnerValue];
}

View file

@ -16,9 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { findByPropsLazy, findLazy } from "@webpack";
import { find, findByProps } from "@webpack";
import * as t from "./types/classes";
export const ModalImageClasses: t.ImageModalClasses = findLazy(m => m.image && m.modal && !m.applicationIcon);
export const ButtonWrapperClasses: t.ButtonWrapperClasses = findByPropsLazy("buttonWrapper", "buttonContent");
export const ModalImageClasses: t.ImageModalClasses = find(m => m.image && m.modal && !m.applicationIcon);
export const ButtonWrapperClasses: t.ButtonWrapperClasses = findByProps("buttonWrapper", "buttonContent");

View file

@ -17,9 +17,8 @@
*/
// eslint-disable-next-line path-alias/no-relative
import { filters, findByPropsLazy, waitFor } from "@webpack";
import { filters, findComponent, findExportedComponent, waitFor } from "@webpack";
import { waitForComponent } from "./internal";
import * as t from "./types/components";
export let Forms = {} as {
@ -53,13 +52,14 @@ export let FocusLock: t.FocusLock;
/** css colour resolver stuff, no clue what exactly this does, just copied usage from Discord */
export let useToken: t.useToken;
export const MaskedLink = waitForComponent<t.MaskedLink>("MaskedLink", filters.componentByCode("MASKED_LINK)"));
export const Timestamp = waitForComponent<t.Timestamp>("Timestamp", filters.byCode(".Messages.MESSAGE_EDITED_TIMESTAMP_A11Y_LABEL.format"));
export const Flex = waitForComponent<t.Flex>("Flex", ["Justify", "Align", "Wrap"]);
export const MaskedLink = findComponent<t.MaskedLinkProps>(filters.componentByCode("MASKED_LINK)"));
export const Timestamp = findComponent<t.TimestampProps>(filters.componentByCode(".Messages.MESSAGE_EDITED_TIMESTAMP_A11Y_LABEL.format"));
export const Flex = findComponent<t.FlexProps>(filters.byProps("Justify", "Align", "Wrap"));
export const { OAuth2AuthorizeModal } = findByPropsLazy("OAuth2AuthorizeModal");
export const OAuth2AuthorizeModal = findExportedComponent("OAuth2AuthorizeModal");
waitFor(["FormItem", "Button"], m => {
waitFor(filters.byProps("FormItem", "Button"), m => {
Forms = m;
({
useToken,
Card,
@ -83,5 +83,4 @@ waitFor(["FormItem", "Button"], m => {
FocusLock,
Heading
} = m);
Forms = m;
});

View file

@ -1,44 +0,0 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2023 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 <https://www.gnu.org/licenses/>.
*/
import { LazyComponent } from "@utils/react";
// eslint-disable-next-line path-alias/no-relative
import { FilterFn, filters, lazyWebpackSearchHistory, waitFor } from "../webpack";
export function waitForComponent<T extends React.ComponentType<any> = React.ComponentType<any> & Record<string, any>>(name: string, filter: FilterFn | string | string[]): T {
if (IS_DEV) lazyWebpackSearchHistory.push(["waitForComponent", Array.isArray(filter) ? filter : [filter]]);
let myValue: T = function () {
throw new Error(`Vencord could not find the ${name} Component`);
} as any;
const lazyComponent = LazyComponent(() => myValue) as T;
waitFor(filter, (v: any) => {
myValue = v;
Object.assign(lazyComponent, v);
}, { isIndirect: true });
return lazyComponent;
}
export function waitForStore(name: string, cb: (v: any) => void) {
if (IS_DEV) lazyWebpackSearchHistory.push(["waitForStore", [name]]);
waitFor(filters.byStoreName(name), cb, { isIndirect: true });
}

View file

@ -17,12 +17,10 @@
*/
// eslint-disable-next-line path-alias/no-relative
import { findByPropsLazy, waitFor } from "../webpack";
import { findByProps } from "../webpack";
import type * as t from "./types/menu";
export let Menu = {} as t.Menu;
export const Menu = findByProps<t.Menu>("MenuItem", "MenuSliderControl");
waitFor(["MenuItem", "MenuSliderControl"], m => Menu = m);
export const ContextMenuApi: t.ContextMenuApi = findByPropsLazy("closeContextMenu", "openContextMenu");
export const ContextMenuApi = findByProps<t.ContextMenuApi>("closeContextMenu", "openContextMenu");

View file

@ -17,7 +17,7 @@
*/
// eslint-disable-next-line path-alias/no-relative
import { findByPropsLazy, waitFor } from "../webpack";
import { filters, findByProps,waitFor } from "../webpack";
export let React: typeof import("react");
export let useState: typeof React.useState;
@ -27,9 +27,9 @@ export let useRef: typeof React.useRef;
export let useReducer: typeof React.useReducer;
export let useCallback: typeof React.useCallback;
export const ReactDOM: typeof import("react-dom") & typeof import("react-dom/client") = findByPropsLazy("createPortal", "render");
export const ReactDOM = findByProps<typeof import("react-dom") & typeof import("react-dom/client")>("createPortal", "render");
waitFor("useState", m => {
waitFor(filters.byProps("useState"), m => {
React = m;
({ useEffect, useState, useMemo, useRef, useReducer, useCallback } = React);
});

Some files were not shown because too many files have changed in this diff Show more