diff --git a/package.json b/package.json index 0f79d21a..723a40cb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vencord", "private": "true", - "version": "1.7.5", + "version": "1.7.7", "description": "The cutest Discord client mod", "homepage": "https://github.com/Vendicated/Vencord#readme", "bugs": { diff --git a/src/plugins/customRPC/index.tsx b/src/plugins/customRPC/index.tsx index e70f8c90..35fb64d1 100644 --- a/src/plugins/customRPC/index.tsx +++ b/src/plugins/customRPC/index.tsx @@ -27,7 +27,6 @@ import { ApplicationAssetUtils, FluxDispatcher, Forms, GuildStore, React, Select const ActivityComponent = findComponentByCodeLazy("onOpenGameProfile"); const ActivityClassName = findByPropsLazy("activity", "buttonColor"); -const Colors = findByPropsLazy("profileColors"); async function getApplicationAsset(key: string): Promise { if (/https?:\/\/(cdn|media)\.discordapp\.(com|net)\/attachments\//.test(key)) return "mp:" + key.replace(/https?:\/\/(cdn|media)\.discordapp\.(com|net)\//, ""); @@ -406,7 +405,7 @@ export default definePlugin({ If you want to use image link, download your image and reupload the image to Imgur and get the image link by right-clicking the image and select "Copy image address". -
+
{activity[0] && "IMAGE"===\i\|\|"VIDEO"===\i;/, + replace: "=>false;" + } }, { find: "renderAttachments(", @@ -51,52 +41,5 @@ export default definePlugin({ replace: "$&$1.content_type?.startsWith('image/')&&" } }, - { - find: "Messages.REMOVE_ATTACHMENT_TOOLTIP_TEXT", - replacement: [{ - match: /\i===\i\.\i\.MOSAIC/, - replace: "true" - }, - { - match: /\i!==\i\.\i\.MOSAIC/, - replace: "false" - }] - }, - { - find: ".messageAttachment,", - replacement: { - match: /\{width:\i,height:\i\}=(\i).*?(?=className:\i\(\)\(\i\.messageAttachment,)/, - replace: "$&style:$self.style($1)," - } - } - ], - - style({ width, height }) { - if (!width || !height) return {}; - - if (width > MAX_WIDTH || height > MAX_HEIGHT) { - if (width / height > MAX_WIDTH / MAX_HEIGHT) { - height = Math.ceil(MAX_WIDTH / (width / height)); - width = MAX_WIDTH; - } else { - width = Math.ceil(MAX_HEIGHT * (width / height)); - height = MAX_HEIGHT; - } - } - - return { - maxWidth: width, - width: "100%", - aspectRatio: `${width} / ${height}` - }; - - }, - - start() { - enableStyle(style); - }, - - stop() { - disableStyle(style); - } + ] }); diff --git a/src/plugins/noMosaic/styles.css b/src/plugins/noMosaic/styles.css deleted file mode 100644 index 3a8a8e46..00000000 --- a/src/plugins/noMosaic/styles.css +++ /dev/null @@ -1,8 +0,0 @@ -[class^="nonMediaAttachmentsContainer_"] [class*="messageAttachment_"] { - position: relative; -} - -[class^="nonMediaAttachmentsContainer_"], -[class^="nonMediaAttachmentItem_"]:has([class^="messageAttachment_"][style^="max-width"]) { - width: 100%; -} diff --git a/src/plugins/pictureInPicture/index.tsx b/src/plugins/pictureInPicture/index.tsx index ca766aff..0a22f06d 100644 --- a/src/plugins/pictureInPicture/index.tsx +++ b/src/plugins/pictureInPicture/index.tsx @@ -10,7 +10,7 @@ import { definePluginSettings } from "@api/Settings"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { React, Tooltip } from "@webpack/common"; +import { Tooltip } from "@webpack/common"; const settings = definePluginSettings({ loop: { @@ -28,9 +28,9 @@ export default definePlugin({ settings, patches: [ { - find: ".nonMediaAttachment]", + find: ".nonMediaMosaicItem]", replacement: { - match: /\.nonMediaAttachment\]:!(\i).{0,10}children:\[(\S)/, + match: /\.nonMediaMosaicItem\]:!(\i).{0,10}children:\[(\S)/, replace: "$&,$1&&$2&&$self.renderPiPButton()," }, }, diff --git a/src/plugins/pronoundb/index.ts b/src/plugins/pronoundb/index.ts index b1e74158..61edd191 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 24cdf2b0..98062912 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/roleColorEverywhere/index.tsx b/src/plugins/roleColorEverywhere/index.tsx index b421eb7f..6d53906f 100644 --- a/src/plugins/roleColorEverywhere/index.tsx +++ b/src/plugins/roleColorEverywhere/index.tsx @@ -94,7 +94,7 @@ export default definePlugin({ find: "renderPrioritySpeaker", replacement: [ { - match: /renderName\(\).{0,100}speaking:.{50,100}jsx.{5,10}{/, + match: /renderName\(\).{0,100}speaking:.{50,150}"div",{/, replace: "$&...$self.getVoiceProps(this.props)," } ], diff --git a/src/plugins/showConnections/index.tsx b/src/plugins/showConnections/index.tsx index 83600e86..ca612292 100644 --- a/src/plugins/showConnections/index.tsx +++ b/src/plugins/showConnections/index.tsx @@ -35,7 +35,7 @@ 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 getTheme: (user: User, displayProfile: any) => any = findByCodeLazy(',"--profile-gradient-primary-color"'); +const getTheme: (user: User, displayProfile: any) => any = findByCodeLazy('--profile-gradient-primary-color":'); const enum Spacing { COMPACT, diff --git a/src/plugins/showMeYourName/index.tsx b/src/plugins/showMeYourName/index.tsx index 62d0645d..a9db1af9 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 ae28631c..105b3b18 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 d7e4f645..06595892 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 6eb773c2..f71777ad 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 0790e8bf..10c7d7ee 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);