diff --git a/scripts/build/build.mts b/scripts/build/build.mts index cc74f0e7..6e936257 100644 --- a/scripts/build/build.mts +++ b/scripts/build/build.mts @@ -23,7 +23,7 @@ import { existsSync, readdirSync } from "fs"; import { readdir, rm, writeFile } from "fs/promises"; import { join } from "path"; -import { addBuild, BUILD_TIMESTAMP, buildOrWatchAll, commonOpts, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, resolvePluginName, VERSION, watch } from "./common.mjs"; +import { addBuild, BUILD_TIMESTAMP, buildOrWatchAll, commonOpts, commonRendererPlugins, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, resolvePluginName, VERSION, watch } from "./common.mjs"; const defines = { IS_STANDALONE: String(IS_STANDALONE), @@ -128,7 +128,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, @@ -232,7 +232,7 @@ await Promise.all([ sourcemap, plugins: [ globPlugins("equicordDesktop"), - ...commonOpts.plugins + ...commonRendererPlugins ], define: { ...defines, diff --git a/scripts/build/buildWeb.mts b/scripts/build/buildWeb.mts index 3cc42ab2..fd465868 100644 --- a/scripts/build/buildWeb.mts +++ b/scripts/build/buildWeb.mts @@ -23,7 +23,7 @@ import { appendFile, mkdir, readdir, readFile, rm, writeFile } from "fs/promises import { join } from "path"; import Zip from "zip-local"; -import { addBuild, BUILD_TIMESTAMP, buildOrWatchAll, commonOpts, globPlugins, IS_DEV, IS_REPORTER, VERSION } from "./common.mjs"; +import { addBuild, BUILD_TIMESTAMP, buildOrWatchAll, commonOpts, commonRendererPlugins, globPlugins, IS_DEV, IS_REPORTER, VERSION } from "./common.mjs"; /** * @type {esbuild.BuildOptions} @@ -36,7 +36,7 @@ const commonOptions: esbuild.BuildOptions = { external: ["~plugins", "~git-hash", "/assets/*"], plugins: [ globPlugins("web"), - ...commonOpts.plugins, + ...commonRendererPlugins ], target: ["esnext"], define: { diff --git a/scripts/build/common.mts b/scripts/build/common.mts index c2321fcf..72d842ca 100644 --- a/scripts/build/common.mts +++ b/scripts/build/common.mts @@ -28,6 +28,7 @@ import { join, relative } from "path"; import { promisify } from "util"; import { getPluginTarget } from "../utils.mjs"; +import { builtinModules } from "module"; const PackageJSON: typeof import("../../package.json") = JSON.parse(readFileSync("package.json", "utf-8")); @@ -262,6 +263,15 @@ export const stylePlugin: Plugin = { } }; +export const banImportPlugin = (filter: RegExp, message: string) => ({ + name: "ban-imports", + setup: build => { + build.onResolve({ filter }, () => { + return { errors: [{ text: message }] }; + }); + } +}); + export const commonOpts = { logLevel: "info", bundle: true, @@ -302,3 +312,15 @@ export async function buildOrWatchAll() { } } } + +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 +]; 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 => ( { 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 3339cb33..0b99f28a 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), diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 07a058c0..ad4b1feb 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -35,10 +35,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