diff --git a/package.json b/package.json index 0f79d21ab..75ef41e50 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vencord", "private": "true", - "version": "1.7.5", + "version": "1.7.6", "description": "The cutest Discord client mod", "homepage": "https://github.com/Vendicated/Vencord#readme", "bugs": { diff --git a/src/plugins/pronoundb/index.ts b/src/plugins/pronoundb/index.ts index b1e74158b..61edd191e 100644 --- a/src/plugins/pronoundb/index.ts +++ b/src/plugins/pronoundb/index.ts @@ -36,25 +36,24 @@ export default definePlugin({ authors: [Devs.Tyman, Devs.TheKodeToad, Devs.Ven], description: "Adds pronouns to user messages using pronoundb", patches: [ - // Add next to username (compact mode) { find: "showCommunicationDisabledStyles", - replacement: { - match: /("span",{id:\i,className:\i,children:\i}\))/, - replace: "$1, $self.CompactPronounsChatComponentWrapper(arguments[0])" - } - }, - // Patch the chat timestamp element (normal mode) - { - find: "showCommunicationDisabledStyles", - replacement: { - match: /(?<=return\s*\(0,\i\.jsxs?\)\(.+!\i&&)(\(0,\i.jsxs?\)\(.+?\{.+?\}\))/, - replace: "[$1, $self.PronounsChatComponentWrapper(arguments[0])]" - } + replacement: [ + // Add next to username (compact mode) + { + match: /("span",{id:\i,className:\i,children:\i}\))/, + replace: "$1, $self.CompactPronounsChatComponentWrapper(arguments[0])" + }, + // Patch the chat timestamp element (normal mode) + { + match: /(?<=return\s*\(0,\i\.jsxs?\)\(.+!\i&&)(\(0,\i.jsxs?\)\(.+?\{.+?\}\))/, + replace: "[$1, $self.PronounsChatComponentWrapper(arguments[0])]" + } + ] }, // Patch the profile popout username header to use our pronoun hook instead of Discord's pronouns { - find: ".userTagNoNickname", + find: ".pronouns,children", replacement: [ { match: /{user:(\i),[^}]*,pronouns:(\i),[^}]*}=\i;/, diff --git a/src/plugins/resurrectHome/index.tsx b/src/plugins/resurrectHome/index.tsx index 24cdf2b02..980629126 100644 --- a/src/plugins/resurrectHome/index.tsx +++ b/src/plugins/resurrectHome/index.tsx @@ -18,9 +18,68 @@ import { findGroupChildrenByChildId } from "@api/ContextMenu"; import { definePluginSettings } from "@api/Settings"; +import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { Menu } from "@webpack/common"; +import { findByPropsLazy } from "@webpack"; +import { Button, Menu, Tooltip, useEffect, useState } from "@webpack/common"; + +const ChannelRowClasses = findByPropsLazy("modeConnected", "modeLocked", "icon"); + +let currentShouldViewServerHome = false; +const shouldViewServerHomeStates = new Set>>(); + +function ViewServerHomeButton() { + return ( + + {tooltipProps => ( + + )} + + ); +} + +function useForceServerHome() { + const { forceServerHome } = settings.use(["forceServerHome"]); + const [shouldViewServerHome, setShouldViewServerHome] = useState(currentShouldViewServerHome); + + useEffect(() => { + shouldViewServerHomeStates.add(setShouldViewServerHome); + + return () => { + shouldViewServerHomeStates.delete(setShouldViewServerHome); + }; + }, []); + + return shouldViewServerHome || forceServerHome; +} + +function useDisableViewServerHome() { + useEffect(() => () => { + currentShouldViewServerHome = false; + for (const setState of shouldViewServerHomeStates) { + setState(false); + } + }, []); +} const settings = definePluginSettings({ forceServerHome: { @@ -30,12 +89,6 @@ const settings = definePluginSettings({ } }); -function useForceServerHome() { - const { forceServerHome } = settings.use(["forceServerHome"]); - - return forceServerHome; -} - export default definePlugin({ name: "ResurrectHome", description: "Re-enables the Server Home tab when there isn't a Server Guide. Also has an option to force the Server Home over the Server Guide, which is accessible through right-clicking the Server Guide.", @@ -92,14 +145,37 @@ export default definePlugin({ match: /getMutableGuildChannelsForGuild\(\i\);return\(0,\i\.useStateFromStores\).+?\]\)(?=}function)/, replace: m => `${m}&&!$self.useForceServerHome()` } + }, + // Add View Server Home Button to Server Guide + { + find: "487e85_1", + replacement: { + match: /(?<=text:(\i)\?\i\.\i\.Messages\.SERVER_GUIDE:\i\.\i\.Messages\.GUILD_HOME,)/, + replace: "badge:$self.ViewServerHomeButton({serverGuide:$1})," + } + }, + // Disable view Server Home override when the Server Home is unmouted + { + find: "69386d_5", + replacement: { + match: /location:"69386d_5".+?;/, + replace: "$&$self.useDisableViewServerHome();" + } } ], + ViewServerHomeButton: ErrorBoundary.wrap(({ serverGuide }: { serverGuide?: boolean; }) => { + if (serverGuide !== true) return null; + + return ; + }), + useForceServerHome, + useDisableViewServerHome, contextMenus: { "guild-context"(children, props) { - const forceServerHome = useForceServerHome(); + const { forceServerHome } = settings.use(["forceServerHome"]); if (!props?.guild) return; diff --git a/src/plugins/showMeYourName/index.tsx b/src/plugins/showMeYourName/index.tsx index 62d0645d2..a9db1af9a 100644 --- a/src/plugins/showMeYourName/index.tsx +++ b/src/plugins/showMeYourName/index.tsx @@ -49,7 +49,7 @@ export default definePlugin({ { find: ".useCanSeeRemixBadge)", replacement: { - match: /(?<=onContextMenu:\i,children:).*?\}/, + match: /(?<=onContextMenu:\i,children:).*?\)}/, replace: "$self.renderUsername(arguments[0])}" } }, diff --git a/src/plugins/spotifyControls/PlayerComponent.tsx b/src/plugins/spotifyControls/PlayerComponent.tsx index ae28631c9..105b3b18a 100644 --- a/src/plugins/spotifyControls/PlayerComponent.tsx +++ b/src/plugins/spotifyControls/PlayerComponent.tsx @@ -18,7 +18,6 @@ import "./spotifyStyles.css"; -import ErrorBoundary from "@components/ErrorBoundary"; import { Flex } from "@components/Flex"; import { ImageIcon, LinkIcon, OpenExternalIcon } from "@components/Icons"; import { debounce } from "@shared/debounce"; @@ -376,17 +375,10 @@ export function Player() { } as React.CSSProperties; return ( - ( -
-

Failed to render Spotify Modal :(

-

Check the console for errors

-
- )}> -
- - - -
-
+
+ + + +
); } diff --git a/src/plugins/spotifyControls/index.tsx b/src/plugins/spotifyControls/index.tsx index d7e4f6454..06595892f 100644 --- a/src/plugins/spotifyControls/index.tsx +++ b/src/plugins/spotifyControls/index.tsx @@ -18,6 +18,7 @@ import { Settings } from "@api/Settings"; import { disableStyle, enableStyle } from "@api/Styles"; +import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; @@ -49,10 +50,10 @@ export default definePlugin({ { find: "showTaglessAccountPanel:", replacement: { - // return React.createElement(AccountPanel, { ..., showTaglessAccountPanel: blah }) - match: /return ?(.{0,30}\(.{1,3},\{[^}]+?,showTaglessAccountPanel:.+?\}\))/, - // return [Player, Panel] - replace: "return [$self.renderPlayer(),$1]" + // react.jsx)(AccountPanel, { ..., showTaglessAccountPanel: blah }) + match: /(?<=\i\.jsxs?\)\()(\i),{(?=[^}]*?showTaglessAccountPanel:)/, + // react.jsx(WrapperComponent, { VencordOriginal: AccountPanel, ... + replace: "$self.PanelWrapper,{VencordOriginal:$1," } }, { @@ -78,6 +79,25 @@ export default definePlugin({ } } ], + start: () => toggleHoverControls(Settings.plugins.SpotifyControls.hoverControls), - renderPlayer: () => + + PanelWrapper({ VencordOriginal, ...props }) { + return ( + <> + ( +
+

Failed to render Spotify Modal :(

+

Check the console for errors

+
+ )} + > + +
+ + + + ); + } }); diff --git a/src/plugins/viewIcons/index.tsx b/src/plugins/viewIcons/index.tsx index 6eb773c28..f71777ad7 100644 --- a/src/plugins/viewIcons/index.tsx +++ b/src/plugins/viewIcons/index.tsx @@ -174,7 +174,7 @@ export default definePlugin({ find: ".NITRO_BANNER,", replacement: { // style: { backgroundImage: shouldShowBanner ? "url(".concat(bannerUrl, - match: /style:\{(?=backgroundImage:(\i)\?"url\("\.concat\((\i),)/, + match: /style:\{(?=backgroundImage:(null!=\i)\?"url\("\.concat\((\i),)/, replace: // onClick: () => shouldShowBanner && ev.target.style.backgroundImage && openImage(bannerUrl), style: { cursor: shouldShowBanner ? "pointer" : void 0, 'onClick:ev=>$1&&ev.target.style.backgroundImage&&$self.openImage($2),style:{cursor:$1?"pointer":void 0,' diff --git a/src/webpack/webpack.ts b/src/webpack/webpack.ts index 0790e8bf1..10c7d7ee1 100644 --- a/src/webpack/webpack.ts +++ b/src/webpack/webpack.ts @@ -406,13 +406,15 @@ export function findExportedComponentLazy(...props: stri }); } +const DefaultExtractAndLoadChunksRegex = /(?:Promise\.all\((\[\i\.\i\(".+?"\).+?\])\)|Promise\.resolve\(\)).then\(\i\.bind\(\i,"(.+?)"\)\)/; + /** * Extract and load chunks using their entry point * @param code An array of all the code the module factory containing the lazy chunk loading must include * @param matcher A RegExp that returns the chunk ids array as the first capture group and the entry point id as the second. Defaults to a matcher that captures the lazy chunk loading found in the module factory * @returns A promise that resolves when the chunks were loaded */ -export async function extractAndLoadChunks(code: string[], matcher: RegExp = /Promise\.all\((\[\i\.\i\(".+?"\).+?\])\).then\(\i\.bind\(\i,"(.+?)"\)\)/) { +export async function extractAndLoadChunks(code: string[], matcher: RegExp = DefaultExtractAndLoadChunksRegex) { const module = findModuleFactory(...code); if (!module) { const err = new Error("extractAndLoadChunks: Couldn't find module factory"); @@ -434,7 +436,7 @@ export async function extractAndLoadChunks(code: string[], matcher: RegExp = /Pr } const [, rawChunkIds, entryPointId] = match; - if (!rawChunkIds || Number.isNaN(entryPointId)) { + if (Number.isNaN(entryPointId)) { const err = new Error("extractAndLoadChunks: Matcher didn't return a capturing group with the chunk ids array, or the entry point id returned as the second group wasn't a number"); logger.warn(err, "Code:", code, "Matcher:", matcher); @@ -445,9 +447,11 @@ export async function extractAndLoadChunks(code: string[], matcher: RegExp = /Pr return; } - const chunkIds = Array.from(rawChunkIds.matchAll(/\("(.+?)"\)/g)).map((m: any) => m[1]); + if (rawChunkIds) { + const chunkIds = Array.from(rawChunkIds.matchAll(/\("(.+?)"\)/g)).map((m: any) => m[1]); + await Promise.all(chunkIds.map(id => wreq.e(id))); + } - await Promise.all(chunkIds.map(id => wreq.e(id))); wreq(entryPointId); } @@ -459,7 +463,7 @@ export async function extractAndLoadChunks(code: string[], matcher: RegExp = /Pr * @param matcher A RegExp that returns the chunk ids array as the first capture group and the entry point id as the second. Defaults to a matcher that captures the lazy chunk loading found in the module factory * @returns A function that returns a promise that resolves when the chunks were loaded, on first call */ -export function extractAndLoadChunksLazy(code: string[], matcher: RegExp = /Promise\.all\((\[\i\.\i\(".+?"\).+?\])\).then\(\i\.bind\(\i,"(.+?)"\)\)/) { +export function extractAndLoadChunksLazy(code: string[], matcher = DefaultExtractAndLoadChunksRegex) { if (IS_DEV) lazyWebpackSearchHistory.push(["extractAndLoadChunks", [code, matcher]]); return () => extractAndLoadChunks(code, matcher);