diff --git a/packages/discord-types/src/classes.d.ts b/packages/discord-types/src/classes.d.ts
deleted file mode 100644
index a7260048..00000000
--- a/packages/discord-types/src/classes.d.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-export interface ButtonWrapperClasses {
- hoverScale: string;
- buttonWrapper: string;
- button: string;
- iconMask: string;
- buttonContent: string;
- icon: string;
- pulseIcon: string;
- pulseButton: string;
- notificationDot: string;
- sparkleContainer: string;
- sparkleStar: string;
- sparklePlus: string;
- sparkle: string;
- active: string;
-}
diff --git a/packages/discord-types/src/index.d.ts b/packages/discord-types/src/index.d.ts
index fdbd65f1..23ab505d 100644
--- a/packages/discord-types/src/index.d.ts
+++ b/packages/discord-types/src/index.d.ts
@@ -1,5 +1,4 @@
export * from "./common";
-export * from "./classes";
export * from "./components";
export * from "./flux";
export * from "./fluxEvents";
diff --git a/src/api/ChatButtons.tsx b/src/api/ChatButtons.tsx
index c2a1a198..ebb5eb5e 100644
--- a/src/api/ChatButtons.tsx
+++ b/src/api/ChatButtons.tsx
@@ -11,15 +11,15 @@ import { Logger } from "@utils/Logger";
import { classes } from "@utils/misc";
import { IconComponent } from "@utils/types";
import { Channel } from "@vencord/discord-types";
-import { waitFor } from "@webpack";
-import { ButtonWrapperClasses, Clickable, Menu, Tooltip } from "@webpack/common";
+import { findCssClassesLazy } from "@webpack";
+import { Clickable, Menu, Tooltip } from "@webpack/common";
import { HTMLProps, JSX, MouseEventHandler, ReactNode } from "react";
import { addContextMenuPatch, findGroupChildrenByChildId } from "./ContextMenu";
import { useSettings } from "./Settings";
-let ChannelTextAreaClasses: Record<"button" | "buttonContainer", string>;
-waitFor(["buttonContainer", "channelTextArea"], m => ChannelTextAreaClasses = m);
+const ButtonWrapperClasses = findCssClassesLazy("button", "buttonWrapper", "notificationDot");
+const ChannelTextAreaClasses = findCssClassesLazy("buttonContainer", "channelTextArea", "button");
export interface ChatBarProps {
channel: Channel;
@@ -113,11 +113,9 @@ function VencordChatBarButtons(props: ChatBarProps) {
}
export function _injectButtons(buttons: ReactNode[], props: ChatBarProps) {
- if (props.disabled) return;
+ if (props.disabled || buttons.length === 0) return;
buttons.unshift();
-
- return buttons;
}
/**
@@ -145,13 +143,13 @@ export const ChatBarButton = ErrorBoundary.wrap((props: ChatBarButtonProps) => {
aria-label={props.tooltip}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
- className={classes(ButtonWrapperClasses?.button, ChannelTextAreaClasses?.button)}
+ className={classes(ButtonWrapperClasses.button, ChannelTextAreaClasses?.button)}
onClick={props.onClick}
onContextMenu={props.onContextMenu}
onAuxClick={props.onAuxClick}
{...props.buttonProps}
>
-
+
{props.children}
diff --git a/src/components/CodeBlock.tsx b/src/components/CodeBlock.tsx
index 29b76265..e85e7ed7 100644
--- a/src/components/CodeBlock.tsx
+++ b/src/components/CodeBlock.tsx
@@ -4,10 +4,10 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
-import { findByPropsLazy } from "@webpack";
+import { findCssClassesLazy } from "@webpack";
import { Parser } from "@webpack/common";
-const CodeContainerClasses = findByPropsLazy("markup", "codeContainer");
+const CodeContainerClasses = findCssClassesLazy("markup", "codeContainer");
/**
* Renders code in a Discord codeblock
diff --git a/src/plugins/_api/chatButtons.ts b/src/plugins/_api/chatButtons.ts
index 5a5969cc..432c66bf 100644
--- a/src/plugins/_api/chatButtons.ts
+++ b/src/plugins/_api/chatButtons.ts
@@ -16,8 +16,8 @@ export default definePlugin({
{
find: '"sticker")',
replacement: {
- match: /(?<=className:.{0,20}\.buttons.{0,50}children:)(\i)/,
- replace: "Vencord.Api.ChatButtons._injectButtons($1,arguments[0])"
+ match: /let (\i)=\(0,\i\.chain\).{0,150}?;(?=return 0===\1\.length)/,
+ replace: "$&Vencord.Api.ChatButtons._injectButtons($1,arguments[0]);"
}
}
]
diff --git a/src/plugins/_api/commands.ts b/src/plugins/_api/commands.ts
index 3a761936..cca1a686 100644
--- a/src/plugins/_api/commands.ts
+++ b/src/plugins/_api/commands.ts
@@ -50,10 +50,10 @@ export default definePlugin({
},
// Show plugin name instead of "Built-In"
{
- find: ".source,children",
+ find: "#{intl::COMMANDS_OPTIONAL_COUNT}",
replacement: {
// ...children: p?.name
- match: /(?<=:(.{1,3})\.displayDescription\}.{0,200}\.source,children:)[^}]+/,
+ match: /(?<=:(\i)\.displayDescription\}.{0,200}children:).{0,50}\.name(?=\}\))/,
replace: "$1.plugin||($&)"
}
}
diff --git a/src/plugins/_api/dynamicImageModalApi.ts b/src/plugins/_api/dynamicImageModalApi.ts
index 114b4836..775cdf03 100644
--- a/src/plugins/_api/dynamicImageModalApi.ts
+++ b/src/plugins/_api/dynamicImageModalApi.ts
@@ -14,7 +14,7 @@ export default definePlugin({
description: "Allows you to omit either width or height when opening an image modal",
patches: [
{
- find: ".dimensionlessImage,",
+ find: ".renderLinkComponent)?",
replacement: {
// widthAndHeightPassed = w != null && w !== 0 && h == null || h === 0
match: /(?<=\i=)(null!=\i&&0!==\i)&&(null!=\i&&0!==\i)/,
diff --git a/src/plugins/_api/memberListDecorators/index.tsx b/src/plugins/_api/memberListDecorators/index.tsx
index 90f09d8f..ab0ba590 100644
--- a/src/plugins/_api/memberListDecorators/index.tsx
+++ b/src/plugins/_api/memberListDecorators/index.tsx
@@ -30,7 +30,7 @@ export default definePlugin({
patches: [
{
- find: ".lostPermission)",
+ find: "#{intl::GUILD_OWNER}),children:",
replacement: [
{
match: /children:\[(?=.{0,300},lostPermissionTooltipText:)/,
diff --git a/src/plugins/_api/messageAccessories.ts b/src/plugins/_api/messageAccessories.ts
index 0ba2a031..f0bf4589 100644
--- a/src/plugins/_api/messageAccessories.ts
+++ b/src/plugins/_api/messageAccessories.ts
@@ -27,8 +27,8 @@ export default definePlugin({
{
find: "#{intl::REMOVE_ATTACHMENT_BODY}",
replacement: {
- match: /(?<=.container\)?,children:)(\[.+?\])/,
- replace: "Vencord.Api.MessageAccessories._modifyAccessories($1,this.props)",
+ match: /children:(\[[^\]]{0,100}?this.renderSuppressConfirmModal[^\]]{0,100}?\])/,
+ replace: "children:Vencord.Api.MessageAccessories._modifyAccessories($1,this.props)",
},
},
],
diff --git a/src/plugins/_api/notices.ts b/src/plugins/_api/notices.ts
index 43ef2acc..89aa1a46 100644
--- a/src/plugins/_api/notices.ts
+++ b/src/plugins/_api/notices.ts
@@ -32,13 +32,6 @@ export default definePlugin({
match: /(?<=!1;)\i=null;(?=.{0,80}getPremiumSubscription\(\))/g,
replace: "if(Vencord.Api.Notices.currentNotice)return false;$&"
},
-
- // FIXME(Bundler minifier change related): Remove the non used compability once enough time has passed
- {
- match: /(?<=,NOTICE_DISMISS:function\(\i\){)return null!=(\i)/,
- replace: (m, notice) => `if(${notice}?.id=="VencordNotice")return(${notice}=null,Vencord.Api.Notices.nextNotice(),true);${m}`,
- noWarn: true,
- },
{
match: /(?<=function (\i)\(\i\){)return null!=(\i)(?=.+?NOTICE_DISMISS:\1)/,
replace: (m, _, notice) => `if(${notice}?.id=="VencordNotice")return(${notice}=null,Vencord.Api.Notices.nextNotice(),true);${m}`
diff --git a/src/plugins/_api/serverList.ts b/src/plugins/_api/serverList.ts
index 89c40796..edbaea69 100644
--- a/src/plugins/_api/serverList.ts
+++ b/src/plugins/_api/serverList.ts
@@ -27,7 +27,7 @@ export default definePlugin({
{
find: "#{intl::DISCODO_DISABLED}",
replacement: {
- match: /(?<=#{intl::DISCODO_DISABLED}.+?return)(\(.{0,75}?tutorialContainer.+?}\))(?=}function)/,
+ match: /(?<=#{intl::DISCODO_DISABLED}.+?return)(\(.{0,150}?tutorialId:"friends-list".+?}\))(?=}function)/,
replace: "[$1].concat(Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.Above))"
}
},
diff --git a/src/plugins/_core/settings.tsx b/src/plugins/_core/settings.tsx
index 052a38ff..d9bcf95f 100644
--- a/src/plugins/_core/settings.tsx
+++ b/src/plugins/_core/settings.tsx
@@ -102,17 +102,17 @@ export default definePlugin({
patches: [
{
- find: ".versionHash",
+ find: "#{intl::COPY_VERSION}",
replacement: [
{
- match: /\.compactInfo.+?(?=null!=(\i)&&(.{0,20}\i\.Text.{0,200}?,children:).{0,15}?("span"),({className:\i\.versionHash,children:\["Build Override: ",\1\.id\]\})\)\}\))/,
+ match: /"text-xxs\/normal".{0,300}?(?=null!=(\i)&&(.{0,20}\i\.Text.{0,200}?,children:).{0,15}?("span"),({className:\i\.\i,children:\["Build Override: ",\1\.id\]\})\)\}\))/,
replace: (m, _buildOverride, makeRow, component, props) => {
props = props.replace(/children:\[.+\]/, "");
return `${m},$self.makeInfoElements(${component},${props}).map(e=>${makeRow}e})),`;
}
},
{
- match: /\.info.+?\[\(0,\i\.jsxs?\)\((.{1,10}),(\{[^{}}]+\{.{0,20}.versionHash,.+?\})\)," "/,
+ match: /"text-xs\/normal".{0,300}?\[\(0,\i\.jsxs?\)\((.{1,10}),(\{[^{}}]+\{.{0,20}className:\i.\i,.+?\})\)," "/,
replace: (m, component, props) => {
props = props.replace(/children:\[.+\]/, "");
return `${m},$self.makeInfoElements(${component},${props})`;
@@ -141,8 +141,8 @@ export default definePlugin({
find: "#{intl::USER_SETTINGS_ACTIONS_MENU_LABEL}",
replacement: {
// Skip the check Discord performs to make sure the section being selected in the user settings context menu is valid
- match: /(?<=function\((\i),(\i),\i\)\{)(?=let \i=Object.values\(\i\.\i\).+?(\(0,\i\.openUserSettings\))\()/,
- replace: (_, settingsPanel, section, openUserSettings) => `${openUserSettings}(${settingsPanel},{section:${section}});return;`
+ match: /null!=\(\i=Object.values\(\i\.\i\).{0,50}?&&(?=\(0,\i\.openUserSettings\)\(\i,\{section:\i)/,
+ replace: ""
}
},
{
diff --git a/src/plugins/alwaysAnimate/index.ts b/src/plugins/alwaysAnimate/index.ts
index 1635781c..8a057c98 100644
--- a/src/plugins/alwaysAnimate/index.ts
+++ b/src/plugins/alwaysAnimate/index.ts
@@ -49,9 +49,9 @@ export default definePlugin({
},
{
// Guild Banner
- find: ".animatedBannerHoverLayer,onMouseEnter:",
+ find: "#{intl::DISCOVERABLE_GUILD_HEADER_PUBLIC_INFO}",
replacement: {
- match: /(\.headerContent.+?guildBanner:\i,animate:)\i/,
+ match: /(guildBanner:\i,animate:)\i(?=}\):null)/,
replace: "$1!0"
}
},
diff --git a/src/plugins/anonymiseFileNames/index.tsx b/src/plugins/anonymiseFileNames/index.tsx
index 62cd7796..985fc4a8 100644
--- a/src/plugins/anonymiseFileNames/index.tsx
+++ b/src/plugins/anonymiseFileNames/index.tsx
@@ -24,7 +24,7 @@ import { CloudUpload } from "@vencord/discord-types";
import { findByCodeLazy } from "@webpack";
import { useState } from "@webpack/common";
-const ActionBarIcon = findByCodeLazy(".actionBarIcon)");
+const ActionBarIcon = findByCodeLazy("Children.map", "isValidElement", "dangerous:");
const enum Methods {
Random,
diff --git a/src/plugins/betterFolders/index.tsx b/src/plugins/betterFolders/index.tsx
index 5a1754d3..cee1a6d0 100644
--- a/src/plugins/betterFolders/index.tsx
+++ b/src/plugins/betterFolders/index.tsx
@@ -178,7 +178,7 @@ export default definePlugin({
},
// If we are rendering the Better Folders sidebar, we filter out everything but the Guild List from the Sidebar children
{
- match: /unreadMentionsFixedFooter\].+?\}\)\]/,
+ match: /reverse:!0,.{0,150}?barClassName:.+?\}\)\]/,
replace: "$&.filter($self.makeGuildsBarSidebarFilter(!!arguments[0]?.isBetterFolders))"
}
]
@@ -212,7 +212,7 @@ export default definePlugin({
// If we are rendering the normal GuildsBar sidebar, we make Discord think the folder is always collapsed to show better icons (the mini guild icons) and avoid transitions
{
predicate: () => settings.store.keepIcons,
- match: /(?<=let{folderNode:\i,setNodeRef:\i,.+?expanded:(\i),.+?;)(?=let)/,
+ match: /(?<=let ?(?:\i,)*?{folderNode:\i,setNodeRef:\i,.+?expanded:(\i),.+?;)(?=let)/,
replace: (_, isExpanded) => `${isExpanded}=!!arguments[0]?.isBetterFolders&&${isExpanded};`
},
// Disable expanding and collapsing folders transition in the normal GuildsBar sidebar
@@ -224,20 +224,20 @@ export default definePlugin({
// If we are rendering the normal GuildsBar sidebar, we avoid rendering guilds from folders that are expanded
{
predicate: () => !settings.store.keepIcons,
- match: /folderGroupBackground.+?,(?=\i\(\(\i,\i,\i\)=>{let{key:.{0,70}"ul")(?<=selected:\i,expanded:(\i),.+?)/,
+ match: /"--custom-folder-color".+?(?=\i\(\(\i,\i,\i\)=>{let{key:.{0,70}"ul")(?<=selected:\i,expanded:(\i),.+?)/,
replace: (m, isExpanded) => `${m}$self.shouldRenderContents(arguments[0],${isExpanded})?null:`
},
// Decide if we should render the expanded folder background if we are rendering the Better Folders sidebar
{
predicate: () => settings.store.showFolderIcon !== FolderIconDisplay.Always,
- match: /\.isExpanded\].{0,110}children:\[/,
+ match: /"--custom-folder-color".{0,110}?children:\[/,
replace: "$&$self.shouldShowFolderIconAndBackground(!!arguments[0]?.isBetterFolders,arguments[0]?.betterFoldersExpandedIds)&&"
},
// Decide if we should render the expanded folder icon if we are rendering the Better Folders sidebar
{
predicate: () => settings.store.showFolderIcon !== FolderIconDisplay.Always,
- match: /(?<=\.folderGroupBackground.*?}\),)(?=\i,)/,
- replace: "!$self.shouldShowFolderIconAndBackground(!!arguments[0]?.isBetterFolders,arguments[0]?.betterFoldersExpandedIds)?null:"
+ match: /"--custom-folder-color".+?className:\i\.\i}\),(?=\i,)/,
+ replace: "$&!$self.shouldShowFolderIconAndBackground(!!arguments[0]?.isBetterFolders,arguments[0]?.betterFoldersExpandedIds)?null:"
}
]
},
@@ -252,12 +252,12 @@ export default definePlugin({
// One is for visual refresh, one is not,
// and each has a bunch of conditions &&ed in front of it.
// Add the betterFolders sidebar to both, keeping the conditions Discord uses.
- match: /(?<=[[,])((?:!?\i&&)+)\(.{0,50}({className:\i\.guilds,themeOverride:\i})\)/g,
+ match: /(?<=[[,])((?:!?\i&&)+)\(.{0,50}({className:\i\.\i,themeOverride:\i})\)/g,
replace: (m, conditions, props) => `${m},${conditions}$self.FolderSideBar(${props})`
},
{
// Add grid styles to fix aligment with other visual refresh elements
- match: /(?<=className:)\i\.base(?=,)/,
+ match: /(?<=className:)\i\.\i(?=,"data-fullscreen")/,
replace: `"${GRID_STYLE_NAME} "+$&`
}
]
diff --git a/src/plugins/betterRoleDot/index.ts b/src/plugins/betterRoleDot/index.ts
index 9928a2a4..d2c8d3f3 100644
--- a/src/plugins/betterRoleDot/index.ts
+++ b/src/plugins/betterRoleDot/index.ts
@@ -29,7 +29,8 @@ export default definePlugin({
patches: [
{
- find: ".dotBorderBase",
+ // Class used in this module is dotBorderBase
+ find: "M0 4C0 1.79086 1.79086 0 4 0H16C18.2091 0 20 1.79086 20 4V16C20 18.2091 18.2091 20 16 20H4C1.79086 20 0 18.2091 0 16V4Z",
replacement: {
match: /,viewBox:"0 0 20 20"/,
replace: "$&,onClick:()=>$self.copyToClipBoard(arguments[0].color),style:{cursor:'pointer'}",
diff --git a/src/plugins/betterSessions/index.tsx b/src/plugins/betterSessions/index.tsx
index 052b5867..78aea613 100644
--- a/src/plugins/betterSessions/index.tsx
+++ b/src/plugins/betterSessions/index.tsx
@@ -23,7 +23,7 @@ import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
-import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
+import { findByPropsLazy, findComponentByCodeLazy, findCssClassesLazy, findStoreLazy } from "@webpack";
import { Constants, React, RestAPI, Tooltip } from "@webpack/common";
import { RenameButton } from "./components/RenameButton";
@@ -33,8 +33,8 @@ import { fetchNamesFromDataStore, getDefaultName, GetOsColor, GetPlatformIcon, s
const AuthSessionsStore = findStoreLazy("AuthSessionsStore");
const UserSettingsModal = findByPropsLazy("saveAccountChanges", "open");
-const TimestampClasses = findByPropsLazy("timestamp", "blockquoteContainer");
-const SessionIconClasses = findByPropsLazy("sessionIcon");
+const TimestampClasses = findCssClassesLazy("timestamp", "blockquoteContainer");
+const SessionIconClasses = findCssClassesLazy("sessionIcon");
const BlobMask = findComponentByCodeLazy("!1,lowerBadgeSize:");
@@ -66,17 +66,17 @@ export default definePlugin({
replacement: [
// Replace children with a single label with state
{
- match: /({variant:"eyebrow",className:\i\.sessionInfoRow,children:).{70,110}{children:"\\xb7"}\),\(0,\i\.\i\)\("span",{children:\i\[\d+\]}\)\]}\)\]/,
+ match: /({variant:"eyebrow",className:\i\.\i,children:).{70,110}{children:"\\xb7"}\),\(0,\i\.\i\)\("span",{children:\i\[\d+\]}\)\]}\)\]/,
replace: "$1$self.renderName(arguments[0])"
},
{
- match: /({variant:"text-sm\/medium",className:\i\.sessionInfoRow,children:.{70,110}{children:"\\xb7"}\),\(0,\i\.\i\)\("span",{children:)(\i\[\d+\])}/,
- replace: "$1$self.renderTimestamp({ ...arguments[0], timeLabel: $2 })}"
+ match: /({variant:"text-sm\/medium",className:\i\.\i,children:.{70,110}{children:"\\xb7"}\),\(0,\i\.\i\)\("span",{children:)(\i\[\d+\])}/,
+ replace: "$1$self.renderTimestamp({...arguments[0],timeLabel:$2})}"
},
// Replace the icon
{
- match: /\.legacySession\),children:\[(?<=,icon:(\i)\}.+?)/,
- replace: "$& $self.renderIcon({ ...arguments[0], DeviceIcon: $1 }), false &&"
+ match: /children:\[(?=.{0,125}?width:"32")(?<=,icon:(\i)\}.+?)/,
+ replace: "children:[$self.renderIcon({...arguments[0],DeviceIcon:$1}),false&&"
}
]
}
diff --git a/src/plugins/betterSettings/index.tsx b/src/plugins/betterSettings/index.tsx
index c3432ab8..2236d2fd 100644
--- a/src/plugins/betterSettings/index.tsx
+++ b/src/plugins/betterSettings/index.tsx
@@ -5,12 +5,13 @@
*/
import { definePluginSettings } from "@api/Settings";
-import { classNameFactory, disableStyle, enableStyle } from "@api/Styles";
+import { disableStyle, enableStyle } from "@api/Styles";
import { buildPluginMenuEntries, buildThemeMenuEntries } from "@plugins/vencordToolbox/menu";
import { Devs } from "@utils/constants";
+import { classNameFactory } from "@utils/css";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
-import { waitFor } from "@webpack";
+import { findCssClassesLazy } from "@webpack";
import { ComponentDispatch, FocusLock, Menu, useEffect, useRef } from "@webpack/common";
import type { HTMLAttributes, ReactElement } from "react";
@@ -19,8 +20,7 @@ import fullHeightStyle from "./fullHeightContext.css?managed";
type SettingsEntry = { section: string, label: string; };
const cl = classNameFactory("");
-let Classes: Record
;
-waitFor(["animating", "baseLayer", "bg", "layer", "layers"], m => Classes = m);
+const Classes = findCssClassesLazy("animating", "baseLayer", "bg", "layer", "layers");
const settings = definePluginSettings({
disableFade: {
@@ -139,8 +139,8 @@ export default definePlugin({
find: "#{intl::USER_SETTINGS_ACTIONS_MENU_LABEL}",
replacement: [
{
- match: /=\[\];if\((\i)(?=\.forEach.{0,100}"logout"!==\i.{0,30}(\i)\.get\(\i\))/,
- replace: "=$self.wrapMap([]);if($self.transformSettingsEntries($1,$2)",
+ match: /=\[\];(\i)(?=\.forEach.{0,100}"logout"!==\i.{0,30}(\i)\.get\(\i\))/,
+ replace: "=$self.wrapMap([]);$self.transformSettingsEntries($1,$2)",
predicate: () => settings.store.organizeMenu
},
{
@@ -160,7 +160,7 @@ export default definePlugin({
// Thus, we sanity check webpack modules
Layer(props: LayerProps) {
try {
- [FocusLock.$$vencordGetWrappedComponent(), ComponentDispatch, Classes].forEach(e => e.test);
+ [FocusLock.$$vencordGetWrappedComponent(), ComponentDispatch, Classes.layer].forEach(e => e.test);
} catch {
new Logger("BetterSettings").error("Failed to find some components");
return props.children;
diff --git a/src/plugins/blurNsfw/index.ts b/src/plugins/blurNsfw/index.ts
index 958bac57..358c986b 100644
--- a/src/plugins/blurNsfw/index.ts
+++ b/src/plugins/blurNsfw/index.ts
@@ -46,10 +46,12 @@ export default definePlugin({
patches: [
{
find: "}renderEmbeds(",
- replacement: [{
- match: /\.container/,
- replace: "$&+(this.props.channel.nsfw? ' vc-nsfw-img': '')"
- }]
+ replacement: [
+ {
+ match: /(\.renderReactions\(\i\).+?className:)/,
+ replace: '$&(this.props?.channel?.nsfw?"vc-nsfw-img ":"")+'
+ }
+ ]
}
],
diff --git a/src/plugins/consoleShortcuts/index.ts b/src/plugins/consoleShortcuts/index.ts
index 188ebe61..c163dd64 100644
--- a/src/plugins/consoleShortcuts/index.ts
+++ b/src/plugins/consoleShortcuts/index.ts
@@ -56,14 +56,14 @@ const define: typeof Object.defineProperty =
};
function makeShortcuts() {
- function newFindWrapper(filterFactory: (...props: any[]) => Webpack.FilterFn) {
+ function newFindWrapper(filterFactory: (...props: any[]) => Webpack.FilterFn, topLevelOnly = false) {
const cache = new Map();
return function (...filterProps: unknown[]) {
const cacheKey = String(filterProps);
if (cache.has(cacheKey)) return cache.get(cacheKey);
- const matches = findAll(filterFactory(...filterProps));
+ const matches = findAll(filterFactory(...filterProps), { topLevelOnly });
const result = (() => {
switch (matches.length) {
@@ -118,6 +118,7 @@ function makeShortcuts() {
findByProps,
findAllByProps: (...props: string[]) => findAll(filters.byProps(...props)),
findByCode: newFindWrapper(filters.byCode),
+ findCssClasses: newFindWrapper(filters.byClassNames, true),
findAllByCode: (code: string) => findAll(filters.byCode(code)),
findComponentByCode: newFindWrapper(filters.componentByCode),
findAllComponentsByCode: (...code: string[]) => findAll(filters.componentByCode(...code)),
diff --git a/src/plugins/copyFileContents/index.tsx b/src/plugins/copyFileContents/index.tsx
index 5bb79515..673a204d 100644
--- a/src/plugins/copyFileContents/index.tsx
+++ b/src/plugins/copyFileContents/index.tsx
@@ -27,7 +27,7 @@ export default definePlugin({
{
find: "#{intl::PREVIEW_BYTES_LEFT}",
replacement: {
- match: /\.footerGap.+?url:\i,fileName:\i,fileSize:\i}\),(?<=fileContents:(\i),bytesLeft:(\i).+?)/g,
+ match: /url:\i,fileName:\i,fileSize:\i}\),(?=.{0,25}setLanguage:)(?<=fileContents:(\i),bytesLeft:(\i).+?)/g,
replace: "$&$self.addCopyButton({fileContents:$1,bytesLeft:$2}),"
}
}
diff --git a/src/plugins/customRPC/index.tsx b/src/plugins/customRPC/index.tsx
index 18e4bec1..8e3328e8 100644
--- a/src/plugins/customRPC/index.tsx
+++ b/src/plugins/customRPC/index.tsx
@@ -36,7 +36,7 @@ import { ApplicationAssetUtils, Button, FluxDispatcher, Forms, React, UserStore
import { RPCSettings } from "./RpcSettings";
const useProfileThemeStyle = findByCodeLazy("profileThemeStyle:", "--profile-gradient-primary-color");
-const ActivityView = findComponentByCodeLazy(".party?(0", ".card");
+const ActivityView = findComponentByCodeLazy(".party?(0", "USER_PROFILE_ACTIVITY");
const ShowCurrentGame = getUserSettingLazy("status", "showCurrentGame")!;
diff --git a/src/plugins/decor/index.tsx b/src/plugins/decor/index.tsx
index 319bc14f..33acebf8 100644
--- a/src/plugins/decor/index.tsx
+++ b/src/plugins/decor/index.tsx
@@ -47,14 +47,14 @@ export default definePlugin({
},
// Decoration modal module
{
- find: ".decorationGridItem,",
+ find: "80,onlyAnimateOnHoverOrFocus:!",
replacement: [
{
- match: /(?<==)\i=>{var{children.{20,200}decorationGridItem/,
+ match: /(?<==)\i=>{let{children.{20,200}isSelected:\i=!1\}=\i/,
replace: "$self.DecorationGridItem=$&",
},
{
- match: /(?<==)\i=>{var{user:\i,avatarDecoration/,
+ match: /(?<==)\i=>{let{user:\i,avatarDecoration/,
replace: "$self.DecorationGridDecoration=$&",
},
// Remove NEW label from decor avatar decorations
@@ -98,7 +98,7 @@ export default definePlugin({
},
...[
'"Message Username"', // Messages
- ".nameplatePreview,{", // Nameplate preview
+ "#{intl::COLLECTIBLES_NAMEPLATE_PREVIEW_A11Y}", // Nameplate preview
"#{intl::ayozFl::raw}", // Avatar preview
].map(find => ({
find,
diff --git a/src/plugins/decor/ui/components/DecorSection.tsx b/src/plugins/decor/ui/components/DecorSection.tsx
index 3209b435..e25c816c 100644
--- a/src/plugins/decor/ui/components/DecorSection.tsx
+++ b/src/plugins/decor/ui/components/DecorSection.tsx
@@ -13,7 +13,7 @@ import { openChangeDecorationModal } from "@plugins/decor/ui/modals/ChangeDecora
import { findComponentByCodeLazy } from "@webpack";
import { useEffect } from "@webpack/common";
-const CustomizationSection = findComponentByCodeLazy(".customizationSectionBackground");
+const CustomizationSection = findComponentByCodeLazy(".DESCRIPTION", "hasBackground:");
export interface DecorSectionProps {
hideTitle?: boolean;
diff --git a/src/plugins/decor/ui/components/SectionedGridList.tsx b/src/plugins/decor/ui/components/SectionedGridList.tsx
index 4352fadd..0e848e99 100644
--- a/src/plugins/decor/ui/components/SectionedGridList.tsx
+++ b/src/plugins/decor/ui/components/SectionedGridList.tsx
@@ -6,13 +6,13 @@
import { cl } from "@plugins/decor/ui";
import { classes } from "@utils/misc";
-import { findByPropsLazy } from "@webpack";
+import { findCssClassesLazy } from "@webpack";
import { React } from "@webpack/common";
import { JSX } from "react";
import Grid, { GridProps } from "./Grid";
-const ScrollerClasses = findByPropsLazy("managedReactiveScroller");
+const ScrollerClasses = findCssClassesLazy("managedReactiveScroller", "thin");
type Section = SectionT & {
items: Array;
diff --git a/src/plugins/decor/ui/index.ts b/src/plugins/decor/ui/index.ts
index 44e58ecc..a10824c5 100644
--- a/src/plugins/decor/ui/index.ts
+++ b/src/plugins/decor/ui/index.ts
@@ -5,10 +5,10 @@
*/
import { classNameFactory } from "@utils/css";
-import { extractAndLoadChunksLazy, findByPropsLazy } from "@webpack";
+import { extractAndLoadChunksLazy, findCssClassesLazy } from "@webpack";
export const cl = classNameFactory("vc-decor-");
-export const DecorationModalStyles = findByPropsLazy("modalPreview", "modalCloseButton", "spinner", "modal");
+export const DecorationModalClasses = findCssClassesLazy("modalPreview", "modalCloseButton", "spinner", "modal");
export const requireAvatarDecorationModal = extractAndLoadChunksLazy(["initialSelectedDecoration:", /initialSelectedDecoration:\i,.{0,300}\i\.e\(/]);
-export const requireCreateStickerModal = extractAndLoadChunksLazy(["stickerInspected]:"]);
+export const requireCreateStickerModal = extractAndLoadChunksLazy([".CREATE_STICKER_MODAL,", "isDisplayingIndividualStickers"]);
diff --git a/src/plugins/decor/ui/modals/ChangeDecorationModal.tsx b/src/plugins/decor/ui/modals/ChangeDecorationModal.tsx
index f784849e..7c595abc 100644
--- a/src/plugins/decor/ui/modals/ChangeDecorationModal.tsx
+++ b/src/plugins/decor/ui/modals/ChangeDecorationModal.tsx
@@ -13,7 +13,7 @@ import { useAuthorizationStore } from "@plugins/decor/lib/stores/AuthorizationSt
import { useCurrentUserDecorationsStore } from "@plugins/decor/lib/stores/CurrentUserDecorationsStore";
import { decorationToAvatarDecoration } from "@plugins/decor/lib/utils/decoration";
import { settings } from "@plugins/decor/settings";
-import { cl, DecorationModalStyles, requireAvatarDecorationModal } from "@plugins/decor/ui";
+import { cl, DecorationModalClasses, requireAvatarDecorationModal } from "@plugins/decor/ui";
import { AvatarDecorationModalPreview } from "@plugins/decor/ui/components";
import DecorationGridCreate from "@plugins/decor/ui/components/DecorationGridCreate";
import DecorationGridNone from "@plugins/decor/ui/components/DecorationGridNone";
@@ -139,7 +139,7 @@ function ChangeDecorationModal(props: ModalProps) {
return
= 49 /* 1*/ && src.charCodeAt(0) <= 57 /* 9*/) {
+ src = "0,function" + src.substring(src.indexOf("("));
}
let i = 0;
@@ -203,6 +204,9 @@ function initWs(isManual = false) {
case "":
results = findAll(parsedArgs[0]);
break;
+ case "CssClasses":
+ results = findAll(filters.byClassNames(...parsedArgs), { topLevelOnly: true });
+ break;
case "ByProps":
results = findAll(filters.byProps(...parsedArgs));
break;
diff --git a/src/plugins/experiments/index.tsx b/src/plugins/experiments/index.tsx
index e01e34b8..cb456fc7 100644
--- a/src/plugins/experiments/index.tsx
+++ b/src/plugins/experiments/index.tsx
@@ -106,7 +106,7 @@ export default definePlugin({
},
// Enable experiment embed on sent experiment links
{
- find: ".experimentOverride,children:",
+ find: '"Clear Treatment "',
replacement: [
{
match: /\i\.isStaff\(\)/,
diff --git a/src/plugins/fakeNitro/index.tsx b/src/plugins/fakeNitro/index.tsx
index c117d512..4a943e11 100644
--- a/src/plugins/fakeNitro/index.tsx
+++ b/src/plugins/fakeNitro/index.tsx
@@ -183,11 +183,11 @@ export default definePlugin({
makeBypassPatches(),
// Patch the emoji picker in voice calls to not be bypassed by fake nitro
{
- find: "emojiItemDisabled]",
+ find: '.getByName("fork_and_knife")',
predicate: () => settings.store.enableEmojiBypass,
replacement: {
- match: /CHAT/,
- replace: "STATUS"
+ match: ".CHAT",
+ replace: ".STATUS"
}
},
{
diff --git a/src/plugins/friendsSince/index.tsx b/src/plugins/friendsSince/index.tsx
index 19d9b164..6197d0c3 100644
--- a/src/plugins/friendsSince/index.tsx
+++ b/src/plugins/friendsSince/index.tsx
@@ -10,14 +10,14 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { getCurrentChannel } from "@utils/discord";
import definePlugin from "@utils/types";
-import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy } from "@webpack";
+import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy, findCssClassesLazy } from "@webpack";
import { RelationshipStore, Text } from "@webpack/common";
-const containerWrapper = findByPropsLazy("memberSinceWrapper");
-const container = findByPropsLazy("memberSince");
+const WrapperClasses = findCssClassesLazy("memberSinceWrapper");
+const ContainerClasses = findCssClassesLazy("memberSince");
const getCreatedAtDate = findByCodeLazy('month:"short",day:"numeric"');
const locale = findByPropsLazy("getLocale");
-const Section = findComponentByCodeLazy("headingVariant:", ".section", ".header");
+const Section = findComponentByCodeLazy("headingVariant:", '"section"', "headingIcon:");
export default definePlugin({
name: "FriendsSince",
@@ -34,7 +34,7 @@ export default definePlugin({
},
// User Profile Modal
{
- find: ".connections,userId:",
+ find: ",applicationRoleConnection:",
replacement: {
match: /#{intl::USER_PROFILE_MEMBER_SINCE}\),.{0,100}userId:(\i\.id),.{0,100}}\)}\),/,
replace: "$&,$self.FriendsSinceComponent({userId:$1,isSidebar:false}),"
@@ -77,8 +77,8 @@ export default definePlugin({
headingColor="text-default"
className="vc-friendsSince-profile-section"
>
-
-
+
+
{!!getCurrentChannel()?.guild_id && (
))}
@@ -445,11 +445,11 @@ export default definePlugin({
{
// Attachment renderer
- find: ".removeMosaicItemHoverButton",
+ find: "#{intl::REMOVE_ATTACHMENT_TOOLTIP_TEXT}",
replacement: [
{
- match: /\[\i\.obscured\]:.+?,(?<=item:(\i).+?)/,
- replace: '$&"messagelogger-deleted-attachment":$1.originalItem?.deleted,'
+ match: /\.SPOILER,(?=\[\i\.\i\]:)/,
+ replace: '$&"messagelogger-deleted-attachment":arguments[0]?.item?.originalItem?.deleted,'
}
]
},
@@ -471,7 +471,7 @@ export default definePlugin({
find: ".SEND_FAILED,",
replacement: {
// Render editHistory behind the message content
- match: /\.isFailed]:.+?children:\[/,
+ match: /\]:\i.isUnsupported.{0,20}?,children:\[/,
replace: "$&arguments[0]?.message?.editHistory?.length>0&&$self.renderEdits(arguments[0]),"
}
},
@@ -480,8 +480,8 @@ export default definePlugin({
find: "#{intl::MESSAGE_EDITED}",
replacement: {
// Make edit marker clickable
- match: /"span",\{(?=className:\i\.edited,)/,
- replace: "$self.EditMarker,{message:arguments[0].message,"
+ match: /(isInline:!1,children:.{0,50}?)"span",\{(?=className:)/,
+ replace: "$1$self.EditMarker,{message:arguments[0].message,"
}
},
diff --git a/src/plugins/mutualGroupDMs/index.tsx b/src/plugins/mutualGroupDMs/index.tsx
index 6909fbd2..63746e06 100644
--- a/src/plugins/mutualGroupDMs/index.tsx
+++ b/src/plugins/mutualGroupDMs/index.tsx
@@ -18,22 +18,24 @@
import "./style.css";
+import { BaseText } from "@components/BaseText";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { isNonNullish } from "@utils/guards";
import { Logger } from "@utils/Logger";
import definePlugin from "@utils/types";
import { Channel, User } from "@vencord/discord-types";
-import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
+import { findByPropsLazy, findComponentByCodeLazy, findCssClassesLazy } from "@webpack";
import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, Text, useMemo, UserStore } from "@webpack/common";
import { JSX } from "react";
const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel");
const UserUtils = findByPropsLazy("getGlobalName");
-const ProfileListClasses = findByPropsLazy("emptyIconFriends", "emptyIconGuilds");
-const MutualsListClasses = findByPropsLazy("row", "icon", "name", "nick");
-const ExpandableList = findComponentByCodeLazy('"PRESS_SECTION"', ".header");
+const ProfileListClasses = findCssClassesLazy("empty", "textContainer", "connectionIcon");
+const TabBarClasses = findCssClassesLazy("tabPanelScroller", "tabBarPanel");
+const MutualsListClasses = findCssClassesLazy("row", "icon", "name", "details");
+const ExpandableList = findComponentByCodeLazy('action:"PRESS_SECTION"', "section");
function getGroupDMName(channel: Channel) {
return channel.name ||
@@ -102,7 +104,7 @@ export default definePlugin({
// Discord adds spacing between each item which pushes our tab off screen.
// set the gap to zero to ensure ours stays on screen
{
- match: /className:\i\.tabBar/,
+ match: /className:\i\.\i(?=,type:"top")/,
replace: '$& + " vc-mutual-gdms-modal-tab-bar"'
}
]
@@ -116,7 +118,7 @@ export default definePlugin({
replace: "$&$self.pushSection($1,arguments[0].user);"
},
{
- match: /\.tabBarPanel,.*?children:(?=.+?section:(\i))/,
+ match: /children:(?=.{0,100}?component:.+?section:(\i))/,
replace: "$&$1==='MUTUAL_GDMS'?$self.renderMutualGDMs(arguments[0]):"
},
// Make the gap between each item smaller so our tab can fit.
@@ -134,7 +136,7 @@ export default definePlugin({
replace: "$&||$self.getMutualGroupDms(arguments[0].user.id).length>0"
},
{
- match: /\.openUserProfileModal.+?\)}\)}\)(?<=,(\i)&&(\i)&&(\(0,\i\.jsxs?\)\(\i\.\i,{className:(\i)\.divider}\)).+?)/,
+ match: /\.openUserProfileModal.+?\)}\)}\)(?<=,(\i)&&(\i)&&(\(0,\i\.jsxs?\)\(\i\.\i,{className:(\i)\.\i}\)).{0,50}?"MUTUAL_FRIENDS".+?)/,
replace: (m, hasMutualGuilds, hasMutualFriends, Divider, classes) => "" +
`${m},$self.renderDMPageList({user:arguments[0].user,hasDivider:${hasMutualGuilds}||${hasMutualFriends},Divider:${Divider},listStyle:${classes}.list})`
}
@@ -172,7 +174,7 @@ export default definePlugin({
return (
@@ -180,8 +182,9 @@ export default definePlugin({
? entries
: (
-
-
No group dms in common
+
+ You don't have any group chats in common
+
)
}
diff --git a/src/plugins/permissionsViewer/components/UserPermissions.tsx b/src/plugins/permissionsViewer/components/UserPermissions.tsx
index 7e0572e5..3b0c1f30 100644
--- a/src/plugins/permissionsViewer/components/UserPermissions.tsx
+++ b/src/plugins/permissionsViewer/components/UserPermissions.tsx
@@ -22,7 +22,7 @@ import { cl, getGuildPermissionSpecMap, getSortedRolesForMember, sortUserRoles }
import { getIntlMessage } from "@utils/discord";
import { classes } from "@utils/misc";
import type { Guild, GuildMember } from "@vencord/discord-types";
-import { filters, findBulk, proxyLazyWebpack } from "@webpack";
+import { findCssClassesLazy } from "@webpack";
import { PermissionsBits, Text, Tooltip, useMemo, UserStore } from "@webpack/common";
import { PermissionsSortOrder, settings } from "..";
@@ -37,14 +37,8 @@ interface UserPermission {
type UserPermissions = Array;
-const { RoleClasses, RoleBorderClasses } = proxyLazyWebpack(() => {
- const [RoleClasses, RoleBorderClasses] = findBulk(
- filters.byProps("role", "roleCircle", "roleName"),
- filters.byProps("roleCircle", "dot", "dotBorderColor")
- ) as Record[];
-
- return { RoleClasses, RoleBorderClasses };
-});
+const RoleClasses = findCssClassesLazy("role", "roleName", "roleRemoveButton", "roleNameOverflow", "root");
+const RoleBorderClasses = findCssClassesLazy("roleCircle", "dot", "dotBorderColor");
interface FakeRoleProps extends React.HTMLAttributes {
text: string;
@@ -56,7 +50,7 @@ function FakeRole({ text, color, ...props }: FakeRoleProps) {
diff --git a/src/plugins/permissionsViewer/index.tsx b/src/plugins/permissionsViewer/index.tsx
index bcf9e55b..37e68a5f 100644
--- a/src/plugins/permissionsViewer/index.tsx
+++ b/src/plugins/permissionsViewer/index.tsx
@@ -27,15 +27,14 @@ import { Devs } from "@utils/constants";
import { classes } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
import type { Guild } from "@vencord/discord-types";
-import { findByPropsLazy } from "@webpack";
+import { findCssClassesLazy } from "@webpack";
import { Button, ChannelStore, Dialog, GuildMemberStore, GuildRoleStore, GuildStore, match, Menu, PermissionsBits, Popout, useRef, UserStore } from "@webpack/common";
import openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from "./components/RolesAndUsersPermissions";
import UserPermissions from "./components/UserPermissions";
import { getSortedRolesForMember, sortPermissionOverwrites } from "./utils";
-const PopoutClasses = findByPropsLazy("container", "scroller", "list");
-const RoleButtonClasses = findByPropsLazy("button", "icon");
+const PopoutClasses = findCssClassesLazy("container", "scroller", "list");
export const enum PermissionsSortOrder {
HighestRole,
diff --git a/src/plugins/pictureInPicture/index.tsx b/src/plugins/pictureInPicture/index.tsx
index 1d75319a..ff8c00eb 100644
--- a/src/plugins/pictureInPicture/index.tsx
+++ b/src/plugins/pictureInPicture/index.tsx
@@ -28,9 +28,9 @@ export default definePlugin({
settings,
patches: [
{
- find: ".removeMosaicItemHoverButton),",
+ find: '["VIDEO","CLIP","AUDIO"]',
replacement: {
- match: /(\.nonMediaMosaicItem\]:.{0,40}children:)(\i.slice\(\i\))(?<=showDownload:(\i).+?isVisualMediaType:(\i).+?)/,
+ match: /(\[\i>0&&\i\.length>0.{0,150}?children:)(\i.slice\(\i\))(?<=showDownload:(\i).+?isVisualMediaType:(\i).+?)/,
replace: (_, rest, origChildren, showDownload, isVisualMediaType) => `${rest}[${showDownload}&&${isVisualMediaType}&&$self.PictureInPictureButton(),...${origChildren}]`
}
}
diff --git a/src/plugins/pinDms/index.tsx b/src/plugins/pinDms/index.tsx
index 53524257..4dfa4dfa 100644
--- a/src/plugins/pinDms/index.tsx
+++ b/src/plugins/pinDms/index.tsx
@@ -12,7 +12,7 @@ import { Devs } from "@utils/constants";
import { classes } from "@utils/misc";
import definePlugin, { OptionType, StartAt } from "@utils/types";
import { Channel } from "@vencord/discord-types";
-import { findByPropsLazy, findStoreLazy } from "@webpack";
+import { findCssClassesLazy, findStoreLazy } from "@webpack";
import { Clickable, ContextMenuApi, FluxDispatcher, Menu, React } from "@webpack/common";
import { contextMenus } from "./components/contextMenu";
@@ -26,7 +26,7 @@ interface ChannelComponentProps {
selected: boolean;
}
-const headerClasses = findByPropsLazy("privateChannelsHeaderContainer");
+const headerClasses = findCssClassesLazy("privateChannelsHeaderContainer", "headerText");
export const PrivateChannelSortStore = findStoreLazy("PrivateChannelSortStore") as { getPrivateChannelIds: () => string[]; };
@@ -72,7 +72,7 @@ export default definePlugin({
patches: [
{
- find: ".privateChannelsHeaderContainer,",
+ find: '"private-channels-".concat(',
replacement: [
{
// Filter out pinned channels from the private channel list
@@ -95,8 +95,8 @@ export default definePlugin({
replace: "$&if($self.isCategoryIndex($1.section))return $self.renderCategory($1);"
},
{
- match: /(?<=span",{)className:\i\.headerText,/,
- replace: "...$self.makeSpanProps(),$&"
+ match: /"renderSection".{0,300}?"span",{/,
+ replace: "$&...$self.makeSpanProps(),"
},
// Fix Row Height
diff --git a/src/plugins/plainFolderIcon/index.ts b/src/plugins/plainFolderIcon/index.ts
index 8eb87896..d7f0bd62 100644
--- a/src/plugins/plainFolderIcon/index.ts
+++ b/src/plugins/plainFolderIcon/index.ts
@@ -28,12 +28,12 @@ export default definePlugin({
patches: [
{
- find: ".folderPreviewGuildIconError",
+ find: "#{intl::GUILD_FOLDER_TOOLTIP_A11Y_LABEL}",
replacement: [
{
// Discord always renders both plain and guild icons folders and uses a css transtion to switch between them
- match: /(?<=.folderButtonContent]:(!\i))/,
- replace: (_, hasFolderButtonContentClass) => `,"vc-plainFolderIcon-plain":${hasFolderButtonContentClass}`
+ match: /\.slice\(0,4\).+?\]:(\i),\[\i\.\i\]:!\1/,
+ replace: (m, hasFolderButtonContent) => `${m},"vc-plainFolderIcon-plain":!${hasFolderButtonContent}`
}
]
diff --git a/src/plugins/replyTimestamp/index.tsx b/src/plugins/replyTimestamp/index.tsx
index dcf70c70..7391153b 100644
--- a/src/plugins/replyTimestamp/index.tsx
+++ b/src/plugins/replyTimestamp/index.tsx
@@ -10,11 +10,11 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import type { Message } from "@vencord/discord-types";
-import { findByPropsLazy } from "@webpack";
+import { findCssClassesLazy } from "@webpack";
import { DateUtils, Timestamp } from "@webpack/common";
import type { HTMLAttributes } from "react";
-const MessageClasses = findByPropsLazy("separator", "latin24CompactTimeStamp");
+const MessageClasses = findCssClassesLazy("separator", "latin24CompactTimeStamp");
function Sep(props: HTMLAttributes
) {
return ;
diff --git a/src/plugins/revealAllSpoilers/index.ts b/src/plugins/revealAllSpoilers/index.ts
index ad1d89f9..814abb20 100644
--- a/src/plugins/revealAllSpoilers/index.ts
+++ b/src/plugins/revealAllSpoilers/index.ts
@@ -18,10 +18,10 @@
import { Devs, IS_MAC } from "@utils/constants";
import definePlugin from "@utils/types";
-import { findByPropsLazy } from "@webpack";
+import { findCssClassesLazy } from "@webpack";
-const SpoilerClasses = findByPropsLazy("spoilerContent");
-const MessagesClasses = findByPropsLazy("messagesWrapper", "navigationDescription");
+const SpoilerClasses = findCssClassesLazy("spoilerContent", "hidden");
+const MessagesClasses = findCssClassesLazy("messagesWrapper", "navigationDescription");
export default definePlugin({
name: "RevealAllSpoilers",
diff --git a/src/plugins/reviewDB/components/MessageButton.tsx b/src/plugins/reviewDB/components/MessageButton.tsx
index 9b0b4be1..10c92db8 100644
--- a/src/plugins/reviewDB/components/MessageButton.tsx
+++ b/src/plugins/reviewDB/components/MessageButton.tsx
@@ -18,10 +18,10 @@
import { DeleteIcon } from "@components/Icons";
import { classes } from "@utils/misc";
-import { findByPropsLazy } from "@webpack";
+import { findCssClassesLazy } from "@webpack";
import { Tooltip } from "@webpack/common";
-const iconClasses = findByPropsLazy("button", "wrapper", "disabled", "separator");
+const iconClasses = findCssClassesLazy("button", "wrapper", "disabled", "separator", "dangerous");
export function DeleteButton({ onClick }: { onClick(): void; }) {
return (
diff --git a/src/plugins/reviewDB/index.tsx b/src/plugins/reviewDB/index.tsx
index 2091687f..1b395f69 100644
--- a/src/plugins/reviewDB/index.tsx
+++ b/src/plugins/reviewDB/index.tsx
@@ -23,10 +23,9 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { NotesIcon, OpenExternalIcon } from "@components/Icons";
import { TooltipContainer } from "@components/TooltipContainer";
import { Devs } from "@utils/constants";
-import { classes } from "@utils/misc";
import definePlugin from "@utils/types";
import { Guild, User } from "@vencord/discord-types";
-import { findByPropsLazy } from "@webpack";
+import { findCssClassesLazy } from "@webpack";
import { Alerts, Clickable, Menu, Parser } from "@webpack/common";
import { Auth, initAuth, updateAuth } from "./auth";
@@ -36,7 +35,7 @@ import { getCurrentUserInfo, readNotification } from "./reviewDbApi";
import { settings } from "./settings";
import { showToast } from "./utils";
-const BannerButtonClasses = findByPropsLazy("bannerButton");
+const BannerButtonClasses = findCssClassesLazy("bannerButton");
const guildPopoutPatch: NavContextMenuPatchCallback = (children, { guild }: { guild: Guild, onClose(): void; }) => {
if (!guild) return;
@@ -152,7 +151,7 @@ export default definePlugin({
openReviewsModal(user.id, user.username, ReviewType.User)}
- className={classes(BannerButtonClasses.bannerButton)}
+ className={BannerButtonClasses.bannerButton}
>
diff --git a/src/plugins/reviewDB/style.css b/src/plugins/reviewDB/style.css
index e65275f8..83fa6cf2 100644
--- a/src/plugins/reviewDB/style.css
+++ b/src/plugins/reviewDB/style.css
@@ -130,4 +130,4 @@
.vc-rdb-block-modal-unblock {
cursor: pointer;
-}
\ No newline at end of file
+}
diff --git a/src/plugins/roleColorEverywhere/index.tsx b/src/plugins/roleColorEverywhere/index.tsx
index bb76af7d..03a71f49 100644
--- a/src/plugins/roleColorEverywhere/index.tsx
+++ b/src/plugins/roleColorEverywhere/index.tsx
@@ -91,7 +91,8 @@ export default definePlugin({
},
// Slate
{
- find: ".userTooltip,children",
+ // Same find as FullUserInChatbox
+ find: ':"text":',
replacement: [
{
match: /let\{id:(\i),guildId:\i,channelId:(\i)[^}]*\}.*?\.\i,{(?=children)/,
@@ -105,8 +106,8 @@ export default definePlugin({
find: 'tutorialId:"whos-online',
replacement: [
{
- match: /(?<=\.roleIcon.{0,15}:null,).{0,150}— ",\i\]\}\)\]/,
- replace: "$self.RoleGroupColor(arguments[0])]"
+ match: /(#{intl::CHANNEL_MEMBERS_A11Y_LABEL}.+}\):null,).{0,100}?— ",\i\]\}\)\]/,
+ replace: (_, rest) => `${rest}$self.RoleGroupColor(arguments[0])]`
},
],
predicate: () => settings.store.memberList
@@ -123,20 +124,21 @@ export default definePlugin({
},
// Voice Users
{
- find: ".usernameSpeaking]:",
+ find: "#{intl::GUEST_NAME_SUFFIX})]",
replacement: [
{
- match: /\.usernameSpeaking\]:.+?,(?=children)(?<=guildId:(\i),.+?user:(\i).+?)/,
- replace: "$&style:$self.getColorStyle($2.id,$1),"
+ match: /#{intl::GUEST_NAME_SUFFIX}.{0,50}?""\](?<=guildId:(\i),.{0,50}?user:(\i).+?)/,
+ replace: "$&,style:$self.getColorStyle($2.id,$1),"
}
],
predicate: () => settings.store.voiceUsers
},
// Reaction List
{
- find: ".reactionDefault",
+ find: "MessageReactions.render:",
replacement: {
- match: /tag:"strong"(?=.{0,50}\i\.name)(?<=onContextMenu:.{0,15}\((\i),(\i),\i\).+?)/,
+ // FIXME: (?:medium|normal) is for stable compat
+ match: /tag:"strong",variant:"text-md\/(?:medium|normal)"(?<=onContextMenu:.{0,15}\((\i),(\i),\i\).+?)/,
replace: "$&,style:$self.getColorStyle($2?.id,$1?.channel?.id)"
},
predicate: () => settings.store.reactorsList,
@@ -145,7 +147,7 @@ export default definePlugin({
{
find: ",reactionVoteCounts",
replacement: {
- match: /\.name,(?="aria-label)/,
+ match: /\.SIZE_32.+?variant:"text-md\/normal",className:\i\.\i,(?="aria-label":)/,
replace: "$&style:$self.getColorStyle(arguments[0]?.user?.id,arguments[0]?.channel?.id),"
},
predicate: () => settings.store.pollResults
@@ -154,7 +156,7 @@ export default definePlugin({
{
find: ".SEND_FAILED,",
replacement: {
- match: /(?<=isUnsupported\]:(\i)\.isUnsupported\}\),)(?=children:\[)/,
+ match: /(?<=\]:(\i)\.isUnsupported.{0,50}?,)(?=children:\[)/,
replace: "style:$self.useMessageColorsStyle($1),"
},
predicate: () => settings.store.colorChatMessages
diff --git a/src/plugins/serverInfo/GuildInfoModal.tsx b/src/plugins/serverInfo/GuildInfoModal.tsx
index 0ed5548c..5e3a23a7 100644
--- a/src/plugins/serverInfo/GuildInfoModal.tsx
+++ b/src/plugins/serverInfo/GuildInfoModal.tsx
@@ -12,10 +12,10 @@ import { classes } from "@utils/misc";
import { ModalRoot, ModalSize, openModal } from "@utils/modal";
import { useAwaiter } from "@utils/react";
import { Guild, User } from "@vencord/discord-types";
-import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
+import { findComponentByCodeLazy, findCssClassesLazy } from "@webpack";
import { FluxDispatcher, Forms, GuildChannelStore, GuildMemberStore, GuildRoleStore, IconUtils, Parser, PresenceStore, RelationshipStore, ScrollerThin, SnowflakeUtils, TabBar, Timestamp, useEffect, UserStore, UserUtils, useState, useStateFromStores } from "@webpack/common";
-const IconClasses = findByPropsLazy("icon", "acronym", "childWrapper");
+const IconClasses = findCssClassesLazy("icon", "acronym", "childWrapper");
const FriendRow = findComponentByCodeLazy("discriminatorClass:", ".isMobileOnline", "getAvatarURL");
const cl = classNameFactory("vc-gp-");
diff --git a/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx b/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx
index 7dec55ac..bb7a361f 100644
--- a/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx
+++ b/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx
@@ -25,7 +25,7 @@ import { sortPermissionOverwrites } from "@plugins/permissionsViewer/utils";
import { classes } from "@utils/misc";
import { formatDuration } from "@utils/text";
import type { Channel } from "@vencord/discord-types";
-import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
+import { findByPropsLazy, findComponentByCodeLazy, findCssClassesLazy } from "@webpack";
import { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, Parser, PermissionsBits, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from "@webpack/common";
import { cl, settings } from "..";
@@ -81,8 +81,7 @@ const enum ChannelFlags {
}
-const ChatScrollClasses = findByPropsLazy("auto", "managedReactiveScroller");
-const ChatClasses = findByPropsLazy("chat", "content", "noChat", "chatContent");
+const ChatScrollClasses = findCssClassesLazy("auto", "managedReactiveScroller", "customTheme");
const ChannelBeginHeader = findComponentByCodeLazy("#{intl::ROLE_REQUIRED_SINGLE_USER_MESSAGE}");
const TagComponent = findComponentByCodeLazy("#{intl::FORUM_TAG_A11Y_FILTER_BY_TAG}");
diff --git a/src/plugins/showHiddenChannels/index.tsx b/src/plugins/showHiddenChannels/index.tsx
index 6d4a4238..484352a1 100644
--- a/src/plugins/showHiddenChannels/index.tsx
+++ b/src/plugins/showHiddenChannels/index.tsx
@@ -25,15 +25,15 @@ import { classNameFactory } from "@utils/css";
import { classes } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
import type { Channel, Role } from "@vencord/discord-types";
-import { findByPropsLazy } from "@webpack";
+import { findCssClassesLazy } from "@webpack";
import { ChannelStore, PermissionsBits, PermissionStore, Tooltip } from "@webpack/common";
import HiddenChannelLockScreen from "./components/HiddenChannelLockScreen";
-const ChannelListClasses = findByPropsLazy("modeMuted", "modeSelected", "unread", "icon");
-
export const cl = classNameFactory("vc-shc-");
+const ChannelListClasses = findCssClassesLazy("modeSelected", "modeMuted", "unread", "icon");
+
const enum ShowMode {
LockIcon,
HiddenIconWithMutedStyle
@@ -106,7 +106,7 @@ export default definePlugin({
replacement: [
{
// Do not show confirmation to join a voice channel when already connected to another if clicking on a hidden voice channel
- match: /(?<=getIgnoredUsersForVoiceChannel\((\i)\.id\);return\()/,
+ match: /(?<=getIgnoredUsersForVoiceChannel\((\i)\.id\)[^;]+?;return\()/,
replace: (_, channel) => `!$self.isHiddenChannel(${channel})&&`
},
{
@@ -166,7 +166,7 @@ export default definePlugin({
replacement: [
// Make the channel appear as muted if it's hidden
{
- match: /\.subtitle,.+?;(?=return\(0,\i\.jsxs?\))(?<={channel:(\i),name:\i,muted:(\i).+?;)/,
+ match: /Children\.count.+?;(?=return\(0,\i\.jsxs?\)\(\i\.\i,{focusTarget:)(?<={channel:(\i),name:\i,muted:(\i).+?;)/,
replace: (m, channel, muted) => `${m}${muted}=$self.isHiddenChannel(${channel})?true:${muted};`
},
// Add the hidden eye icon if the channel is hidden
@@ -176,7 +176,7 @@ export default definePlugin({
},
// Make voice channels also appear as muted if they are muted
{
- match: /(?<=\.wrapper:\i\.notInteractive,)(.+?)if\((\i)(?:\)return |\?)(\i\.MUTED)/,
+ match: /(?<=\?\i\.\i:\i\.\i,)(.{0,150}?)if\((\i)(?:\)return |\?)(\i\.MUTED)/,
replace: (_, otherClasses, isMuted, mutedClassExpression) => `${isMuted}?${mutedClassExpression}:"",${otherClasses}if(${isMuted})return ""`
}
]
@@ -193,7 +193,7 @@ export default definePlugin({
{
// Hide unreads
predicate: () => settings.store.hideUnreads === true,
- match: /\.subtitle,.+?;(?=return\(0,\i\.jsxs?\))(?<={channel:(\i),name:\i,.+?unread:(\i).+?)/,
+ match: /Children\.count.+?;(?=return\(0,\i\.jsxs?\)\(\i\.\i,{focusTarget:)(?<={channel:(\i),name:\i,.+?unread:(\i).+?)/,
replace: (m, channel, unread) => `${m}${unread}=$self.isHiddenChannel(${channel})?false:${unread};`
}
]
@@ -301,7 +301,7 @@ export default definePlugin({
},
{
// Patch the header to only return allowed users and roles if it's a hidden channel or locked channel (Like when it's used on the HiddenChannelLockScreen)
- match: /return\(0,\i\.jsxs?\)\(\i\.\i,{channelId:(\i)\.id(?=.+?(\(0,\i\.jsxs?\)\("div",{className:\i\.members.+?\]}\)),)/,
+ match: /return\(0,\i\.jsxs?\)\(\i\.\i,{channelId:(\i)\.id(?=.+?(\(0,\i\.jsxs?\)\("div",{className:\i\.\i,children:\[.{0,100}\i\.length>0.+?\]}\)),)/,
replace: (m, channel, allowedUsersAndRolesComponent) => `if($self.isHiddenChannel(${channel},true)){return${allowedUsersAndRolesComponent};}${m}`
},
{
@@ -368,7 +368,7 @@ export default definePlugin({
},
{
// Disable bad CSS class which mess up hidden voice channels styling
- match: /callContainer,(?<=\i\.callContainer,)/,
+ match: /(?=\i\|\|\i!==\i\.\i\.FULL_SCREEN.{0,100}?this\._callContainerRef)/,
replace: '$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel,true)?"":'
}
]
@@ -408,7 +408,7 @@ export default definePlugin({
},
{
// Remove the open chat button for the HiddenChannelLockScreen
- match: /(?<=&&)\(0,\i\.jsxs?\).{0,180}\.buttonIcon/,
+ match: /(?<="participants-list-button"\),!\i&&)\(0,\i\.jsxs?\).{0,280}?iconClassName:/,
replace: "!$self.isHiddenChannel(arguments[0]?.channel,true)&&$&"
}
]
@@ -438,10 +438,10 @@ export default definePlugin({
},
},
{
- find: 'className:"channelMention",children',
+ find: 'className:"channelMention",children:',
replacement: {
// Show inside voice channel instead of trying to join them when clicking on a channel mention
- match: /(?<=getChannel\(\i\);if\(null!=(\i))(?=.{0,100}?selectVoiceChannel)/,
+ match: /(?<=getChannel\(\i\);null!=(\i))(?=.{0,100}?selectVoiceChannel)/,
replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})`
}
},
@@ -461,7 +461,7 @@ export default definePlugin({
]
},
{
- find: ".invitesDisabledTooltip",
+ find: "GuildTooltip - ",
replacement: {
// Make GuildChannelStore.getChannels return hidden channels
match: /(?<=getChannels\(\i)(?=\))/,
diff --git a/src/plugins/showHiddenChannels/style.css b/src/plugins/showHiddenChannels/style.css
index c7c70c5c..2aa0e76e 100644
--- a/src/plugins/showHiddenChannels/style.css
+++ b/src/plugins/showHiddenChannels/style.css
@@ -104,4 +104,4 @@
cursor: not-allowed;
margin-left: 6px;
z-index: 0;
-}
\ No newline at end of file
+}
diff --git a/src/plugins/showHiddenThings/index.ts b/src/plugins/showHiddenThings/index.ts
index 318e2bc7..b788a8bd 100644
--- a/src/plugins/showHiddenThings/index.ts
+++ b/src/plugins/showHiddenThings/index.ts
@@ -72,8 +72,8 @@ export default definePlugin({
find: "#{intl::GUILD_MEMBER_MOD_VIEW_HIGHEST_ROLE}),children:",
predicate: () => settings.store.showModView,
replacement: {
- match: /(?<=\.highestRole\),)role:\i(?<=\[\i\.roles,\i\.highestRoleId,(\i)\].+)/,
- replace: "role:$self.getHighestRole(arguments[0],$1)",
+ match: /(#{intl::GUILD_MEMBER_MOD_VIEW_HIGHEST_ROLE}.{0,80})role:\i(?<=\[\i\.roles,\i\.highestRoleId,(\i)\].+?)/,
+ replace: (_, rest, roles) => `${rest}role:$self.getHighestRole(arguments[0],${roles})`,
}
},
// allows you to open mod view on yourself
diff --git a/src/plugins/sortFriendRequests/index.tsx b/src/plugins/sortFriendRequests/index.tsx
index 8d7b2df6..11a14c15 100644
--- a/src/plugins/sortFriendRequests/index.tsx
+++ b/src/plugins/sortFriendRequests/index.tsx
@@ -65,7 +65,7 @@ export default definePlugin({
find: "#{intl::FRIEND_REQUEST_CANCEL}",
replacement: {
predicate: () => settings.store.showDates,
- match: /(?<=\.listItemContents,children:\[)\(0,.+?(?=,\(0)(?<=user:(\i).+?)/,
+ match: /(?<=children:\[)\(0,.{0,100}user:\i,hovered:\i.+?(?=,\(0)(?<=user:(\i).+?)/,
replace: (children, user) => `$self.WrapperDateComponent({user:${user},children:${children}})`
}
}],
diff --git a/src/plugins/spotifyControls/index.tsx b/src/plugins/spotifyControls/index.tsx
index c7e8c91f..f0c00313 100644
--- a/src/plugins/spotifyControls/index.tsx
+++ b/src/plugins/spotifyControls/index.tsx
@@ -53,7 +53,7 @@ export default definePlugin({
},
patches: [
{
- find: "this.isCopiedStreakGodlike",
+ find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
replacement: {
// react.jsx)(AccountPanel, { ..., showTaglessAccountPanel: blah })
match: /(?<=\i\.jsxs?\)\()(\i),{(?=[^}]*?userTag:\i,hidePrivateData:)/,
diff --git a/src/plugins/superReactionTweaks/index.ts b/src/plugins/superReactionTweaks/index.ts
index a8827903..84cd04e9 100644
--- a/src/plugins/superReactionTweaks/index.ts
+++ b/src/plugins/superReactionTweaks/index.ts
@@ -42,13 +42,6 @@ export default definePlugin({
{
find: ",BURST_REACTION_EFFECT_PLAY",
replacement: [
- // FIXME(Bundler minifier change related): Remove the non used compability once enough time has passed
- {
- // if (inlinedCalculatePlayingCount(a,b) >= limit) return;
- match: /(BURST_REACTION_EFFECT_PLAY:\i=>{.+?if\()(\(\(\i,\i\)=>.+?\(\i,\i\))>=5+?(?=\))/,
- replace: (_, rest, playingCount) => `${rest}!$self.shouldPlayBurstReaction(${playingCount})`,
- noWarn: true,
- },
{
/*
* var limit = 5
diff --git a/src/plugins/themeAttributes/index.ts b/src/plugins/themeAttributes/index.ts
index beb108af..9cb95874 100644
--- a/src/plugins/themeAttributes/index.ts
+++ b/src/plugins/themeAttributes/index.ts
@@ -29,10 +29,10 @@ export default definePlugin({
// Add data-author-id and data-is-self to all messages
{
- find: ".messageListItem",
+ find: "Message must not be a thread starter message",
replacement: {
- match: /\.messageListItem(?=,"aria)/,
- replace: "$&,...$self.getMessageProps(arguments[0])"
+ match: /"aria-setsize":-1,(?=.{0,150}?#{intl::MESSAGE_A11Y_ROLE_DESCRIPTION})/,
+ replace: "...$self.getMessageProps(arguments[0]),$&"
}
},
diff --git a/src/plugins/typingIndicator/index.tsx b/src/plugins/typingIndicator/index.tsx
index ecd8c44d..2e7c9cff 100644
--- a/src/plugins/typingIndicator/index.tsx
+++ b/src/plugins/typingIndicator/index.tsx
@@ -27,7 +27,7 @@ import definePlugin, { OptionType } from "@utils/types";
import { findComponentByCodeLazy } from "@webpack";
import { GuildMemberStore, RelationshipStore, SelectedChannelStore, Tooltip, TypingStore, UserGuildSettingsStore, UserStore, UserSummaryItem, useStateFromStores } from "@webpack/common";
-const ThreeDots = findComponentByCodeLazy(".dots,", "dotRadius:");
+const ThreeDots = findComponentByCodeLazy("Math.min(1,Math.max(", "dotRadius:");
const enum IndicatorMode {
Dots = 1 << 0,
diff --git a/src/plugins/userMessagesPronouns/PronounsChatComponent.tsx b/src/plugins/userMessagesPronouns/PronounsChatComponent.tsx
index b4c32638..4c380e93 100644
--- a/src/plugins/userMessagesPronouns/PronounsChatComponent.tsx
+++ b/src/plugins/userMessagesPronouns/PronounsChatComponent.tsx
@@ -21,13 +21,13 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { getIntlMessage } from "@utils/discord";
import { classes } from "@utils/misc";
import { Message } from "@vencord/discord-types";
-import { findByPropsLazy } from "@webpack";
+import { findCssClassesLazy } from "@webpack";
import { Tooltip, UserStore } from "@webpack/common";
import { settings } from "./settings";
import { useFormattedPronouns } from "./utils";
-const styles: Record = findByPropsLazy("timestampInline");
+const TimestampClasses = findCssClassesLazy("timestampInline", "timestamp");
const MessageDisplayCompact = getUserSettingLazy("textAndImages", "messageDisplayCompact")!;
const AUTO_MODERATION_ACTION = 24;
@@ -49,7 +49,7 @@ function PronounsChatComponent({ message }: { message: Message; }) {
{tooltipProps => (
• {pronouns}
)}
diff --git a/src/plugins/userVoiceShow/components.tsx b/src/plugins/userVoiceShow/components.tsx
index 34201445..71c7e9b0 100644
--- a/src/plugins/userVoiceShow/components.tsx
+++ b/src/plugins/userVoiceShow/components.tsx
@@ -10,18 +10,15 @@ import ShowHiddenChannelsPlugin from "@plugins/showHiddenChannels";
import { classNameFactory } from "@utils/css";
import { classes } from "@utils/misc";
import { Channel } from "@vencord/discord-types";
-import { filters, findByPropsLazy, mapMangledModuleLazy } from "@webpack";
+import { findByPropsLazy, findCssClassesLazy } from "@webpack";
import { ChannelRouter, ChannelStore, Parser, PermissionsBits, PermissionStore, React, showToast, Text, Toasts, Tooltip, useMemo, UserStore, UserSummaryItem, useStateFromStores, VoiceStateStore } from "@webpack/common";
import { PropsWithChildren } from "react";
const cl = classNameFactory("vc-uvs-");
const { selectVoiceChannel } = findByPropsLazy("selectVoiceChannel", "selectChannel");
-const { useChannelName } = mapMangledModuleLazy("#{intl::GROUP_DM_ALONE}", {
- useChannelName: filters.byCode("()=>null==")
-});
-const ActionButtonClasses = findByPropsLazy("actionButton", "highlight");
+const ActionButtonClasses = findCssClassesLazy("actionButton", "highlight");
type IconProps = Omit, "children"> & {
size?: number;
diff --git a/src/plugins/userVoiceShow/index.tsx b/src/plugins/userVoiceShow/index.tsx
index 04b9aa11..039982dd 100644
--- a/src/plugins/userVoiceShow/index.tsx
+++ b/src/plugins/userVoiceShow/index.tsx
@@ -87,7 +87,7 @@ export default definePlugin({
{
find: "null!=this.peopleListItemRef.current",
replacement: {
- match: /\.actions,children:\[(?<=isFocused:(\i).+?)/,
+ match: /\.isProvisional.{0,50}?className:\i\.\i,children:\[(?<=isFocused:(\i).+?)/,
replace: "$&$self.VoiceChannelIndicator({userId:this?.props?.user?.id,isActionButton:true,shouldHighlight:$1}),"
},
predicate: () => settings.store.showInMemberList
diff --git a/src/plugins/vencordToolbox/index.tsx b/src/plugins/vencordToolbox/index.tsx
index 1cac4009..22dfd948 100644
--- a/src/plugins/vencordToolbox/index.tsx
+++ b/src/plugins/vencordToolbox/index.tsx
@@ -28,7 +28,7 @@ import type { PropsWithChildren } from "react";
import { renderPopout } from "./menu";
-const HeaderBarIcon = findComponentByCodeLazy(".HEADER_BAR_BADGE_TOP:", '.iconBadge,"top"');
+const HeaderBarIcon = findComponentByCodeLazy(".HEADER_BAR_BADGE_TOP:", '"aria-haspopup":');
export const settings = definePluginSettings({
showPluginMenu: {
diff --git a/src/plugins/viewIcons/index.tsx b/src/plugins/viewIcons/index.tsx
index 44bee1e1..891a2c7c 100644
--- a/src/plugins/viewIcons/index.tsx
+++ b/src/plugins/viewIcons/index.tsx
@@ -197,21 +197,18 @@ export default definePlugin({
patches: [
// Avatar component used in User DMs "User Profile" popup in the right and User Profile Modal pfp
{
- find: ".overlay:void 0,status:",
- replacement: [
- {
- match: /avatarSrc:(\i),eventHandlers:(\i).+?"div",.{0,100}className:\i,/,
- replace: "$&style:{cursor:\"pointer\"},onClick:()=>{$self.openAvatar($1)},",
- }
- ],
- all: true
+ find: "imageClassName:null!=",
+ replacement: {
+ match: /avatarSrc:(\i),eventHandlers:(\i).+?"div",.{0,100}className:\i,/,
+ replace: "$&style:{cursor:\"pointer\"},onClick:()=>{$self.openAvatar($1)},",
+ }
},
// Banners
{
find: 'backgroundColor:"COMPLETE"',
replacement: {
- match: /(\.banner,.+?),style:{(?=.+?backgroundImage:null!=(\i)\?"url\("\.concat\(\2,)/,
- replace: (_, rest, bannerSrc) => `${rest},onClick:()=>${bannerSrc}!=null&&$self.openBanner(${bannerSrc}),style:{cursor:${bannerSrc}!=null?"pointer":void 0,`
+ match: /(overflow:"visible",.{0,125}?!1\),)style:{(?=.+?backgroundImage:null!=(\i)\?"url\("\.concat\(\2,)/,
+ replace: (_, rest, bannerSrc) => `${rest}onClick:()=>${bannerSrc}!=null&&$self.openBanner(${bannerSrc}),style:{cursor:${bannerSrc}!=null?"pointer":void 0,`
}
},
// Group DMs top small & large icon
@@ -225,7 +222,7 @@ export default definePlugin({
},
// User DMs top small icon
{
- find: ".cursorPointer:null,children",
+ find: ".channel.getRecipientId(),",
replacement: {
match: /(?=,src:(\i.getAvatarURL\(.+?[)]))/,
replace: (_, avatarUrl) => `,onClick:()=>$self.openAvatar(${avatarUrl})`
diff --git a/src/plugins/voiceDownload/index.tsx b/src/plugins/voiceDownload/index.tsx
index 571c3d0e..19d0883f 100644
--- a/src/plugins/voiceDownload/index.tsx
+++ b/src/plugins/voiceDownload/index.tsx
@@ -15,10 +15,10 @@ export default definePlugin({
authors: [Devs.puv],
patches: [
{
- find: "rippleContainer,children",
+ find: "#{intl::LgCPMt::raw}",
replacement: {
- match: /\(0,\i\.jsx\).{0,150},children:.{0,50}\("source",{src:(\i)}\)}\)/,
- replace: "[$&, $self.renderDownload($1)]"
+ match: /(?<=onVolumeHide:\i\}\))/,
+ replace: ",$self.renderDownload(arguments[0].src)"
}
}
],
diff --git a/src/plugins/voiceDownload/style.css b/src/plugins/voiceDownload/style.css
index 4e1379e2..b261bbe1 100644
--- a/src/plugins/voiceDownload/style.css
+++ b/src/plugins/voiceDownload/style.css
@@ -2,11 +2,10 @@
width: 24px;
height: 24px;
color: var(--interactive-icon-default);
- margin-left: 12px;
cursor: pointer;
position: relative;
}
.vc-voice-download:hover {
color: var(--interactive-icon-active);
-}
\ No newline at end of file
+}
diff --git a/src/plugins/voiceMessages/index.tsx b/src/plugins/voiceMessages/index.tsx
index 886ada85..5528aa6f 100644
--- a/src/plugins/voiceMessages/index.tsx
+++ b/src/plugins/voiceMessages/index.tsx
@@ -32,7 +32,7 @@ import definePlugin from "@utils/types";
import { chooseFile } from "@utils/web";
import { CloudUpload as TCloudUpload } from "@vencord/discord-types";
import { CloudUploadPlatform } from "@vencord/discord-types/enums";
-import { findByPropsLazy, findLazy, findStoreLazy } from "@webpack";
+import { findCssClassesLazy, findLazy, findStoreLazy } from "@webpack";
import { Button, Constants, FluxDispatcher, Forms, lodash, Menu, MessageActions, PermissionsBits, PermissionStore, RestAPI, SelectedChannelStore, showToast, SnowflakeUtils, Toasts, useEffect, useState } from "@webpack/common";
import { ComponentType } from "react";
@@ -43,7 +43,7 @@ import { VoiceRecorderWeb } from "./WebRecorder";
const CloudUpload: typeof TCloudUpload = findLazy(m => m.prototype?.trackUploadFinished);
const PendingReplyStore = findStoreLazy("PendingReplyStore");
-const OptionClasses = findByPropsLazy("optionName", "optionIcon", "optionLabel");
+const OptionClasses = findCssClassesLazy("optionName", "optionIcon", "optionLabel");
export const cl = classNameFactory("vc-vmsg-");
export type VoiceRecorder = ComponentType<{
diff --git a/src/plugins/whoReacted/index.tsx b/src/plugins/whoReacted/index.tsx
index fa9bfab5..72330116 100644
--- a/src/plugins/whoReacted/index.tsx
+++ b/src/plugins/whoReacted/index.tsx
@@ -23,10 +23,8 @@ import { Queue } from "@utils/Queue";
import { useForceUpdater } from "@utils/react";
import definePlugin from "@utils/types";
import { CustomEmoji, Message, ReactionEmoji, User } from "@vencord/discord-types";
-import { findByPropsLazy } from "@webpack";
import { ChannelStore, Constants, FluxDispatcher, React, RestAPI, useEffect, useLayoutEffect, UserStore, UserSummaryItem } from "@webpack/common";
-const AvatarStyles = findByPropsLazy("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar");
let Scroll: any = null;
const queue = new Queue();
let reactions: Record;
diff --git a/src/webpack/common/classes.ts b/src/webpack/common/classes.ts
deleted file mode 100644
index daaf023c..00000000
--- a/src/webpack/common/classes.ts
+++ /dev/null
@@ -1,22 +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 .
-*/
-
-import * as t from "@vencord/discord-types";
-import { findByPropsLazy } from "@webpack";
-
-export const ButtonWrapperClasses: t.ButtonWrapperClasses = findByPropsLazy("buttonWrapper", "buttonContent");
diff --git a/src/webpack/common/components.ts b/src/webpack/common/components.ts
index e388a8a1..f06f830f 100644
--- a/src/webpack/common/components.ts
+++ b/src/webpack/common/components.ts
@@ -26,7 +26,7 @@ import { TooltipContainer as TooltipContainerComponent } from "@components/Toolt
import { TooltipFallback } from "@components/TooltipFallback";
import { LazyComponent } from "@utils/lazyReact";
import * as t from "@vencord/discord-types";
-import { filters, mapMangledModuleLazy, waitFor } from "@webpack";
+import { filters, find, findCssClassesLazy, mapMangledCssClasses, mapMangledModuleLazy, proxyLazyWebpack, waitFor } from "@webpack";
import { waitForComponent } from "./internal";
@@ -50,9 +50,7 @@ export const Button = ButtonCompat;
/** @deprecated Use FormSwitch from Vencord */
export const Switch = FormSwitchCompat as never;
-/** @deprecated Use Card from Vencord */
-export const Card = waitForComponent("Card", filters.componentByCode(".editable),", ".outline:"));
-export const Checkbox = waitForComponent("Checkbox", filters.componentByCode(".checkboxWrapperDisabled:"));
+export const Checkbox = waitForComponent("Checkbox", filters.componentByCode('"data-toggleable-component":"checkbox'));
export const Tooltip = waitForComponent("Tooltip", m => m.prototype?.shouldShowTooltip && m.prototype.render, TooltipFallback);
/** @deprecated import from @vencord/components */
@@ -77,19 +75,26 @@ export const UserSummaryItem = waitForComponent("UserSummaryItem", filters.compo
export let createScroller: (scrollbarClassName: string, fadeClassName: string, customThemeClassName: string) => t.ScrollerThin;
export let createListScroller: (scrollBarClassName: string, fadeClassName: string, someOtherClassIdkMan: string, resizeObserverClass: typeof ResizeObserver) => t.ListScrollerThin;
-export let scrollerClasses: Record;
-export let listScrollerClasses: Record;
+
+const listScrollerClassnames = ["thin", "auto", "fade"] as const;
+export const scrollerClasses = findCssClassesLazy("thin", "auto", "fade", "customTheme", "none");
+
+const isListScroller = filters.byClassNames(...listScrollerClassnames);
+const isNotNormalScroller = filters.byClassNames("customTheme");
+export const listScrollerClasses = proxyLazyWebpack(() => {
+ const mod = find(m => isListScroller(m) && !isNotNormalScroller(m), { topLevelOnly: true });
+ if (!mod) return {} as Record;
+
+ return mapMangledCssClasses(mod, listScrollerClassnames);
+});
waitFor(filters.byCode('="ltr",orientation:', "customTheme:", "forwardRef"), m => createScroller = m);
waitFor(filters.byCode("getScrollerNode:", "resizeObserver:", "sectionHeight:"), m => createListScroller = m);
-waitFor(["thin", "auto", "customTheme"], m => scrollerClasses = m);
-waitFor(m => m.thin && m.auto && !m.customTheme, m => listScrollerClasses = m);
export const ScrollerNone = LazyComponent(() => createScroller(scrollerClasses.none, scrollerClasses.fade, scrollerClasses.customTheme));
export const ScrollerThin = LazyComponent(() => createScroller(scrollerClasses.thin, scrollerClasses.fade, scrollerClasses.customTheme));
export const ScrollerAuto = LazyComponent(() => createScroller(scrollerClasses.auto, scrollerClasses.fade, scrollerClasses.customTheme));
-export const ListScrollerNone = LazyComponent(() => createListScroller(listScrollerClasses.none, listScrollerClasses.fade, "", ResizeObserver));
export const ListScrollerThin = LazyComponent(() => createListScroller(listScrollerClasses.thin, listScrollerClasses.fade, "", ResizeObserver));
export const ListScrollerAuto = LazyComponent(() => createListScroller(listScrollerClasses.auto, listScrollerClasses.fade, "", ResizeObserver));
@@ -107,7 +112,7 @@ waitFor(m => {
export const MaskedLink = waitForComponent("MaskedLink", filters.componentByCode("MASKED_LINK)"));
export const Timestamp = waitForComponent("Timestamp", filters.componentByCode("#{intl::MESSAGE_EDITED_TIMESTAMP_A11Y_LABEL}"));
-export const OAuth2AuthorizeModal = waitForComponent("OAuth2AuthorizeModal", filters.componentByCode(".authorize,children:", ".contentBackground"));
+export const OAuth2AuthorizeModal = waitForComponent("OAuth2AuthorizeModal", filters.componentByCode("hasContentBackground", "oauth2_authorize"));
export const Animations = mapMangledModuleLazy(".assign({colorNames:", {
Transition: filters.componentByCode('["items","children"]', ",null,"),
diff --git a/src/webpack/common/index.ts b/src/webpack/common/index.ts
index 80223b9a..f75507e9 100644
--- a/src/webpack/common/index.ts
+++ b/src/webpack/common/index.ts
@@ -16,7 +16,6 @@
* along with this program. If not, see .
*/
-export * from "./classes";
export * from "./components";
export * from "./menu";
export * from "./react";
diff --git a/src/webpack/common/menu.ts b/src/webpack/common/menu.ts
index 7e5447ce..4029877f 100644
--- a/src/webpack/common/menu.ts
+++ b/src/webpack/common/menu.ts
@@ -41,7 +41,7 @@ waitFor(m => m.name === "MenuCheckboxItem", (_, id) => {
});
waitFor(filters.componentByCode('path:["empty"]'), m => Menu.Menu = m);
-waitFor(filters.componentByCode("sliderContainer", "slider", "handleSize:16", "=100"), m => Menu.MenuSliderControl = m);
+waitFor(filters.componentByCode("SLIDER)", "handleSize:16"), m => Menu.MenuSliderControl = m);
waitFor(filters.componentByCode(".SEARCH)", ".focus()", "query:"), m => Menu.MenuSearchControl = m);
export const ContextMenuApi: t.ContextMenuApi = mapMangledModuleLazy('type:"CONTEXT_MENU_OPEN', {
diff --git a/src/webpack/common/utils.ts b/src/webpack/common/utils.ts
index c23a8e66..c76c3ead 100644
--- a/src/webpack/common/utils.ts
+++ b/src/webpack/common/utils.ts
@@ -148,7 +148,7 @@ export const ApplicationAssetUtils = mapMangledModuleLazy("getAssetImage: size m
getAssets: filters.byCode(".assets")
});
-export const NavigationRouter: t.NavigationRouter = mapMangledModuleLazy("Transitioning to ", {
+export const NavigationRouter: t.NavigationRouter = mapMangledModuleLazy("transitionTo - Transitioning to", {
transitionTo: filters.byCode("transitionTo -"),
transitionToGuild: filters.byCode("transitionToGuild -"),
back: filters.byCode("goBack()"),
diff --git a/src/webpack/webpack.ts b/src/webpack/webpack.ts
index 1dcb43a9..c025a72b 100644
--- a/src/webpack/webpack.ts
+++ b/src/webpack/webpack.ts
@@ -256,7 +256,7 @@ export const find = traceFunction("find", function find(filter: FilterFn, { isIn
return isWaitFor ? [null, null] : null;
});
-export function findAll(filter: FilterFn) {
+export function findAll(filter: FilterFn, { topLevelOnly = false }: { topLevelOnly?: boolean; } = {}) {
if (typeof filter !== "function")
throw new Error("Invalid filter. Expected a function got " + typeof filter);
@@ -268,7 +268,7 @@ export function findAll(filter: FilterFn) {
if (filter(mod.exports))
ret.push(mod.exports);
- if (typeof mod.exports !== "object")
+ if (typeof mod.exports !== "object" || topLevelOnly)
continue;
for (const nestedMod in mod.exports) {
@@ -389,7 +389,7 @@ export function findModuleFactory(...code: CodeFilter) {
return wreq.m[id];
}
-export const lazyWebpackSearchHistory = [] as Array<["find" | "findByProps" | "findByCode" | "findStore" | "findComponent" | "findComponentByCode" | "findExportedComponent" | "waitFor" | "waitForComponent" | "waitForStore" | "proxyLazyWebpack" | "LazyComponentWebpack" | "extractAndLoadChunks" | "mapMangledModule", any[]]>;
+export const lazyWebpackSearchHistory = [] as Array<["find" | "findByProps" | "findByCode" | "findCssClasses" | "findStore" | "findComponent" | "findComponentByCode" | "findExportedComponent" | "waitFor" | "waitForComponent" | "waitForStore" | "proxyLazyWebpack" | "LazyComponentWebpack" | "extractAndLoadChunks" | "mapMangledModule", any[]]>;
/**
* This is just a wrapper around {@link proxyLazy} to make our reporter test for your webpack finds.
@@ -578,23 +578,32 @@ export function findExportedComponentLazy(...props: Prop
});
}
-export function findCssClasses(...classes: S[]): Record {
- const res = find(filters.byClassNames(...classes), { isIndirect: true, topLevelOnly: true });
-
- if (!res)
- handleModuleNotFound("findCssClasses", ...classes);
-
- const values = Object.values(res);
+export function mapMangledCssClasses(mappedModule: object, classes: S[] | ReadonlyArray): Record {
+ const values = Object.values(mappedModule);
const mapped = {} as Record;
for (const cls of classes) {
const re = makeClassNameRegex(cls);
mapped[cls] = values.find(v => typeof v === "string" && re.test(v)) as string;
+
+ if (!mapped[cls]) // this should never happen unless this is used manually with invalid input
+ throw new Error(`mapMangledCssClasses: Invalid input. ${cls} not found in module`);
}
return mapped;
}
+export function findCssClasses(...classes: S[]): Record {
+ const res = find(filters.byClassNames(...classes), { isIndirect: true, topLevelOnly: true });
+
+ if (!res) {
+ handleModuleNotFound("findCssClasses", ...classes);
+ return {} as Record;
+ }
+
+ return mapMangledCssClasses(res, classes);
+}
+
export function findCssClassesLazy(...classes: S[]) {
if (IS_REPORTER) lazyWebpackSearchHistory.push(["findCssClasses", classes]);