From 4e3c178043a538245db37d109929fe3378d929a7 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Sat, 10 Aug 2024 16:30:39 +0200 Subject: [PATCH 1/5] fix MutualGroupDMs --- src/plugins/mutualGroupDMs/index.tsx | 37 ++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/plugins/mutualGroupDMs/index.tsx b/src/plugins/mutualGroupDMs/index.tsx index 27850143..7c71e1ed 100644 --- a/src/plugins/mutualGroupDMs/index.tsx +++ b/src/plugins/mutualGroupDMs/index.tsx @@ -21,7 +21,7 @@ import { Devs } from "@utils/constants"; import { isNonNullish } from "@utils/guards"; import definePlugin from "@utils/types"; import { findByPropsLazy } from "@webpack"; -import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, UserStore } from "@webpack/common"; +import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, useMemo, UserStore } from "@webpack/common"; import { Channel, User } from "discord-types/general"; const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel"); @@ -39,6 +39,19 @@ function getGroupDMName(channel: Channel) { .join(", "); } +const getMutualGroupDms = (userId: string) => + ChannelStore.getSortedPrivateChannels() + .filter(c => c.isGroupDM() && c.recipients.includes(userId)); + +const isBotOrSelf = (user: User) => user.bot || user.id === UserStore.getCurrentUser().id; + +function getMutualGDMCountText(user: User) { + const count = getMutualGroupDms(user.id).length; + return `${count === 0 ? "No" : count} Mutual Group${count !== 1 ? "s" : ""}`; +} + +const IS_PATCHED = Symbol("MutualGroupDMs.Patched"); + export default definePlugin({ name: "MutualGroupDMs", description: "Shows mutual group dms in profiles", @@ -63,8 +76,8 @@ export default definePlugin({ find: ".MUTUAL_FRIENDS?(", replacement: [ { - match: /(?<=onItemSelect:\i,children:)(\i)\.map/, - replace: "[...$1, ...($self.isBotOrSelf(arguments[0].user) ? [] : [{section:'MUTUAL_GDMS',text:$self.getMutualGDMCountText(arguments[0].user)}])].map" + match: /\i\.useEffect.{0,100}(\i)\[0\]\.section/, + replace: "$self.pushSection($1, arguments[0].user);$&" }, { match: /\(0,\i\.jsx\)\(\i,\{items:\i,section:(\i)/, @@ -74,15 +87,23 @@ export default definePlugin({ } ], - isBotOrSelf: (user: User) => user.bot || user.id === UserStore.getCurrentUser().id, + isBotOrSelf, + getMutualGDMCountText, - getMutualGDMCountText: (user: User) => { - const count = ChannelStore.getSortedPrivateChannels().filter(c => c.isGroupDM() && c.recipients.includes(user.id)).length; - return `${count === 0 ? "No" : count} Mutual Group${count !== 1 ? "s" : ""}`; + pushSection(sections: any[], user: User) { + if (isBotOrSelf(user) || sections[IS_PATCHED]) return; + + sections[IS_PATCHED] = true; + sections.push({ + section: "MUTUAL_GDMS", + text: getMutualGDMCountText(user) + }); }, renderMutualGDMs: ErrorBoundary.wrap(({ user, onClose }: { user: User, onClose: () => void; }) => { - const entries = ChannelStore.getSortedPrivateChannels().filter(c => c.isGroupDM() && c.recipients.includes(user.id)).map(c => ( + const mutualDms = useMemo(() => getMutualGroupDms(user.id), [user.id]); + + const entries = mutualDms.map(c => ( { From 003e4a08d5c9af1e387a9d95ac3f79df813e9b45 Mon Sep 17 00:00:00 2001 From: Lumap Date: Sat, 10 Aug 2024 16:39:33 +0200 Subject: [PATCH 2/5] fix PictureInPicture (#2773) Co-authored-by: v --- src/plugins/pictureInPicture/index.tsx | 6 +++--- src/utils/constants.ts | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/pictureInPicture/index.tsx b/src/plugins/pictureInPicture/index.tsx index 81d75a25..20cedf45 100644 --- a/src/plugins/pictureInPicture/index.tsx +++ b/src/plugins/pictureInPicture/index.tsx @@ -24,13 +24,13 @@ const settings = definePluginSettings({ export default definePlugin({ name: "PictureInPicture", description: "Adds picture in picture to videos (next to the Download button)", - authors: [Devs.Nobody], + authors: [Devs.Lumap], settings, patches: [ { - find: ".nonMediaMosaicItem]", + find: ".removeMosaicItemHoverButton),", replacement: { - match: /\.nonMediaMosaicItem\]:!(\i).{0,50}?children:\[(\S)/, + match: /\.nonMediaMosaicItem\]:!(\i).{0,50}?children:\[\S,(\S)/, replace: "$&,$1&&$2&&$self.renderPiPButton()," }, }, diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 35525cd1..febb8f9a 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -33,10 +33,6 @@ export interface Dev { * If you are fine with attribution but don't want the badge, add badge: false */ export const Devs = /* #__PURE__*/ Object.freeze({ - Nobody: { - name: "Nobody", - id: 0n, - }, Ven: { name: "Vee", id: 343383572805058560n @@ -545,7 +541,11 @@ export const Devs = /* #__PURE__*/ Object.freeze({ surgedevs: { name: "Chloe", id: 1084592643784331324n - } + }, + Lumap: { + name: "Lumap", + id: 585278686291427338n, + }, } satisfies Record); // iife so #__PURE__ works correctly From 87e6fa8647b6ddfcd73036fd62f2357ed820d510 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Sat, 10 Aug 2024 17:25:40 +0200 Subject: [PATCH 3/5] build: improve errors when breaking module boundaries --- scripts/build/build.mjs | 6 +++--- scripts/build/buildWeb.mjs | 11 ++++++++--- scripts/build/common.mjs | 25 +++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/scripts/build/build.mjs b/scripts/build/build.mjs index 817c2cec..623f9f94 100755 --- a/scripts/build/build.mjs +++ b/scripts/build/build.mjs @@ -21,7 +21,7 @@ import esbuild from "esbuild"; import { readdir } from "fs/promises"; import { join } from "path"; -import { BUILD_TIMESTAMP, commonOpts, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, resolvePluginName, VERSION, watch } from "./common.mjs"; +import { BUILD_TIMESTAMP, commonOpts, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, resolvePluginName, VERSION, commonRendererPlugins, watch } from "./common.mjs"; const defines = { IS_STANDALONE, @@ -131,7 +131,7 @@ await Promise.all([ sourcemap, plugins: [ globPlugins("discordDesktop"), - ...commonOpts.plugins + ...commonRendererPlugins ], define: { ...defines, @@ -180,7 +180,7 @@ await Promise.all([ sourcemap, plugins: [ globPlugins("vencordDesktop"), - ...commonOpts.plugins + ...commonRendererPlugins ], define: { ...defines, diff --git a/scripts/build/buildWeb.mjs b/scripts/build/buildWeb.mjs index bc15ccce..deab8661 100644 --- a/scripts/build/buildWeb.mjs +++ b/scripts/build/buildWeb.mjs @@ -23,7 +23,7 @@ import { appendFile, mkdir, readdir, readFile, rm, writeFile } from "fs/promises import { join } from "path"; import Zip from "zip-local"; -import { BUILD_TIMESTAMP, commonOpts, globPlugins, IS_DEV, IS_REPORTER, VERSION } from "./common.mjs"; +import { BUILD_TIMESTAMP, commonOpts, globPlugins, IS_DEV, IS_REPORTER, VERSION, commonRendererPlugins } from "./common.mjs"; /** * @type {esbuild.BuildOptions} @@ -36,7 +36,7 @@ const commonOptions = { external: ["~plugins", "~git-hash", "/assets/*"], plugins: [ globPlugins("web"), - ...commonOpts.plugins, + ...commonRendererPlugins ], target: ["esnext"], define: { @@ -116,7 +116,12 @@ await Promise.all( } }) ] -); +).catch(err => { + console.error("Build failed"); + console.error(err.message); + if (!commonOpts.watch) + process.exit(1); +});; /** * @type {(dir: string) => Promise} diff --git a/scripts/build/common.mjs b/scripts/build/common.mjs index c46a559a..247557e3 100644 --- a/scripts/build/common.mjs +++ b/scripts/build/common.mjs @@ -28,6 +28,7 @@ import { join, relative } from "path"; import { promisify } from "util"; import { getPluginTarget } from "../utils.mjs"; +import { builtinModules } from "module"; /** @type {import("../../package.json")} */ const PackageJSON = JSON.parse(readFileSync("package.json")); @@ -292,6 +293,18 @@ export const stylePlugin = { } }; +/** + * @type {(filter: RegExp, message: string) => import("esbuild").Plugin} + */ +export const banImportPlugin = (filter, message) => ({ + name: "ban-imports", + setup: build => { + build.onResolve({ filter }, () => { + return { errors: [{ text: message }] }; + }); + } +}); + /** * @type {import("esbuild").BuildOptions} */ @@ -311,3 +324,15 @@ export const commonOpts = { // Work around https://github.com/evanw/esbuild/issues/2460 tsconfig: "./scripts/build/tsconfig.esbuild.json" }; + +const escapedBuiltinModules = builtinModules + .map(m => m.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&")) + .join("|"); +const builtinModuleRegex = new RegExp(`^(node:)?(${escapedBuiltinModules})$`); + +export const commonRendererPlugins = [ + banImportPlugin(builtinModuleRegex, "Cannot import node inbuilt modules in browser code. You need to use a native.ts file"), + banImportPlugin(/^react$/, "Cannot import from react. React and hooks should be imported from @webpack/common"), + banImportPlugin(/^electron(\/.*)?$/, "Cannot import electron in browser code. You need to use a native.ts file"), + ...commonOpts.plugins +]; From 1a712e75a61d6f8462bca5b37dd2dfb169edc5bb Mon Sep 17 00:00:00 2001 From: Joona <69722179+Masterjoona@users.noreply.github.com> Date: Sat, 10 Aug 2024 19:35:21 +0300 Subject: [PATCH 4/5] fix(SpotifyControls): sync with external shuffle toggles (#2767) Co-authored-by: v --- src/plugins/spotifyControls/SpotifyStore.ts | 2 ++ src/plugins/spotifyControls/index.tsx | 23 ++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/plugins/spotifyControls/SpotifyStore.ts b/src/plugins/spotifyControls/SpotifyStore.ts index 7fdd6bba..5c0c5fe4 100644 --- a/src/plugins/spotifyControls/SpotifyStore.ts +++ b/src/plugins/spotifyControls/SpotifyStore.ts @@ -55,6 +55,7 @@ interface PlayerState { // added by patch actual_repeat: Repeat; + shuffle: boolean; } interface Device { @@ -182,6 +183,7 @@ export const SpotifyStore = proxyLazyWebpack(() => { store.isPlaying = e.isPlaying ?? false; store.volume = e.volumePercent ?? 0; store.repeat = e.actual_repeat || "off"; + store.shuffle = e.shuffle ?? false; store.position = e.position ?? 0; store.isSettingPosition = false; store.emitChange(); diff --git a/src/plugins/spotifyControls/index.tsx b/src/plugins/spotifyControls/index.tsx index ae5fbcd8..1e15ef56 100644 --- a/src/plugins/spotifyControls/index.tsx +++ b/src/plugins/spotifyControls/index.tsx @@ -70,21 +70,20 @@ export default definePlugin({ replace: "false", }] }, - // Discord doesn't give you the repeat kind, only a boolean { find: 'repeat:"off"!==', - replacement: { - match: /repeat:"off"!==(.{1,3}),/, - replace: "actual_repeat:$1,$&" - } + replacement: [ + { + // Discord doesn't give you shuffle state and the repeat kind, only a boolean + match: /repeat:"off"!==(\i),/, + replace: "shuffle:arguments[2]?.shuffle_state??false,actual_repeat:$1,$&" + }, + { + match: /(?<=artists.filter\(\i=>).{0,10}\i\.id\)&&/, + replace: "" + } + ] }, - { - find: "artists.filter", - replacement: { - match: /(?<=artists.filter\(\i=>).{0,10}\i\.id\)&&/, - replace: "" - } - } ], start: () => toggleHoverControls(Settings.plugins.SpotifyControls.hoverControls), From 4301ed889d59d34f7b3364dfc9fc401cf412eae7 Mon Sep 17 00:00:00 2001 From: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Date: Tue, 13 Aug 2024 01:50:17 -0300 Subject: [PATCH 5/5] Fix ShowHiddenThings feature & PauseInvitesForever --- src/plugins/pauseInvitesForever/index.tsx | 7 +------ src/plugins/showHiddenThings/index.ts | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/plugins/pauseInvitesForever/index.tsx b/src/plugins/pauseInvitesForever/index.tsx index 3f1ce6bf..666f0af8 100644 --- a/src/plugins/pauseInvitesForever/index.tsx +++ b/src/plugins/pauseInvitesForever/index.tsx @@ -19,16 +19,11 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; -import { findLazy } from "@webpack"; import { Constants, GuildStore, i18n, RestAPI } from "@webpack/common"; -const InvitesDisabledExperiment = findLazy(m => m.definition?.id === "2022-07_invites_disabled"); - function showDisableInvites(guildId: string) { - // Once the experiment is removed, this should keep working - const { enableInvitesDisabled } = InvitesDisabledExperiment?.getCurrentConfig?.({ guildId }) ?? { enableInvitesDisabled: true }; // @ts-ignore - return enableInvitesDisabled && !GuildStore.getGuild(guildId).hasFeature("INVITES_DISABLED"); + return !GuildStore.getGuild(guildId).hasFeature("INVITES_DISABLED"); } function disableInvites(guildId: string) { diff --git a/src/plugins/showHiddenThings/index.ts b/src/plugins/showHiddenThings/index.ts index f01dc210..9ffaa7e1 100644 --- a/src/plugins/showHiddenThings/index.ts +++ b/src/plugins/showHiddenThings/index.ts @@ -51,7 +51,7 @@ export default definePlugin({ }, }, { - find: "2022-07_invites_disabled", + find: "INVITES_DISABLED))||", predicate: () => settings.store.showInvitesPaused, replacement: { match: /\i\.\i\.can\(\i\.\i.MANAGE_GUILD,\i\)/,