mirror of
https://github.com/Vendicated/Vencord.git
synced 2024-09-20 14:40:34 +00:00
Merge branch 'dev' of https://github.com/Vendicated/Vencord into discord-types
This commit is contained in:
commit
1ae49f4d5b
6 changed files with 95 additions and 49 deletions
|
@ -21,9 +21,9 @@ import esbuild from "esbuild";
|
||||||
import { readdir } from "fs/promises";
|
import { readdir } from "fs/promises";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
|
|
||||||
import { BUILD_TIMESTAMP, commonOpts, disposeAll, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, rebuildAll, resolvePluginName, VERSION, watch, watchAll } from "./common.mjs";
|
import { BUILD_TIMESTAMP, commonOpts, commonRendererPlugins, disposeAll, exists, globPlugins, IS_DEV, IS_REPORTER, IS_STANDALONE, IS_UPDATER_DISABLED, rebuildAll, resolvePluginName, VERSION, watch, watchAll } from "./common.mjs";
|
||||||
|
|
||||||
/** @type {Record<string, any>} */
|
/** @type {Record<string, string>} */
|
||||||
const defines = {
|
const defines = {
|
||||||
IS_STANDALONE: IS_STANDALONE.toString(),
|
IS_STANDALONE: IS_STANDALONE.toString(),
|
||||||
IS_DEV: IS_DEV.toString(),
|
IS_DEV: IS_DEV.toString(),
|
||||||
|
@ -35,7 +35,7 @@ const defines = {
|
||||||
BUILD_TIMESTAMP: BUILD_TIMESTAMP.toString()
|
BUILD_TIMESTAMP: BUILD_TIMESTAMP.toString()
|
||||||
};
|
};
|
||||||
|
|
||||||
if (defines.IS_STANDALONE === false)
|
if (defines.IS_STANDALONE === "false")
|
||||||
// If this is a local build (not standalone), optimize
|
// If this is a local build (not standalone), optimize
|
||||||
// for the specific platform we're on
|
// for the specific platform we're on
|
||||||
defines["process.platform"] = JSON.stringify(process.platform);
|
defines["process.platform"] = JSON.stringify(process.platform);
|
||||||
|
@ -129,7 +129,7 @@ const contexts = await Promise.all([
|
||||||
sourcemap,
|
sourcemap,
|
||||||
plugins: [
|
plugins: [
|
||||||
globPlugins("discordDesktop"),
|
globPlugins("discordDesktop"),
|
||||||
...commonOpts.plugins
|
...commonRendererPlugins
|
||||||
],
|
],
|
||||||
define: {
|
define: {
|
||||||
...defines,
|
...defines,
|
||||||
|
@ -177,7 +177,7 @@ const contexts = await Promise.all([
|
||||||
sourcemap,
|
sourcemap,
|
||||||
plugins: [
|
plugins: [
|
||||||
globPlugins("vencordDesktop"),
|
globPlugins("vencordDesktop"),
|
||||||
...commonOpts.plugins
|
...commonRendererPlugins
|
||||||
],
|
],
|
||||||
define: {
|
define: {
|
||||||
...defines,
|
...defines,
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { join } from "path";
|
||||||
// @ts-expect-error: No types
|
// @ts-expect-error: No types
|
||||||
import Zip from "zip-local";
|
import Zip from "zip-local";
|
||||||
|
|
||||||
import { BUILD_TIMESTAMP, commonOpts, disposeAll, globPlugins, IS_DEV, IS_REPORTER, rebuildAll, VERSION, watch, watchAll } from "./common.mjs";
|
import { BUILD_TIMESTAMP, commonOpts, commonRendererPlugins, disposeAll, globPlugins, IS_DEV, IS_REPORTER, rebuildAll, VERSION, watch, watchAll } from "./common.mjs";
|
||||||
|
|
||||||
/** @satisfies {esbuild.BuildOptions} */
|
/** @satisfies {esbuild.BuildOptions} */
|
||||||
const commonOptions = {
|
const commonOptions = {
|
||||||
|
@ -35,7 +35,7 @@ const commonOptions = {
|
||||||
external: ["~plugins", "~git-hash", "/assets/*"],
|
external: ["~plugins", "~git-hash", "/assets/*"],
|
||||||
plugins: [
|
plugins: [
|
||||||
globPlugins("web"),
|
globPlugins("web"),
|
||||||
...commonOpts.plugins,
|
...commonRendererPlugins
|
||||||
],
|
],
|
||||||
target: ["esnext"],
|
target: ["esnext"],
|
||||||
define: {
|
define: {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import esbuild from "esbuild";
|
||||||
import { constants as FsConstants, readFileSync } from "fs";
|
import { constants as FsConstants, readFileSync } from "fs";
|
||||||
import { access, readdir, readFile } from "fs/promises";
|
import { access, readdir, readFile } from "fs/promises";
|
||||||
import { minify as minifyHtml } from "html-minifier-terser";
|
import { minify as minifyHtml } from "html-minifier-terser";
|
||||||
|
import { builtinModules } from "module";
|
||||||
import { join, relative } from "path";
|
import { join, relative } from "path";
|
||||||
import { promisify } from "util";
|
import { promisify } from "util";
|
||||||
|
|
||||||
|
@ -301,6 +302,20 @@ export const rebuildAll = contexts =>
|
||||||
/** @param {esbuild.BuildContext[]} contexts */
|
/** @param {esbuild.BuildContext[]} contexts */
|
||||||
export const watchAll = contexts => Promise.all(contexts.map(ctx => ctx.watch()));
|
export const watchAll = contexts => Promise.all(contexts.map(ctx => ctx.watch()));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {RegExp} filter
|
||||||
|
* @param {string} message
|
||||||
|
* @returns {esbuild.Plugin}
|
||||||
|
*/
|
||||||
|
export const banImportPlugin = (filter, message) => ({
|
||||||
|
name: "ban-imports",
|
||||||
|
setup: build => {
|
||||||
|
build.onResolve({ filter }, () => {
|
||||||
|
return { errors: [{ text: message }] };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/** @satisfies {esbuild.BuildOptions} */
|
/** @satisfies {esbuild.BuildOptions} */
|
||||||
export const commonOpts = {
|
export const commonOpts = {
|
||||||
// Does not work with esbuild.BuildContext.rebuild: https://github.com/evanw/esbuild/issues/2886#issuecomment-1416397046
|
// Does not work with esbuild.BuildContext.rebuild: https://github.com/evanw/esbuild/issues/2886#issuecomment-1416397046
|
||||||
|
@ -319,3 +334,15 @@ export const commonOpts = {
|
||||||
// Work around https://github.com/evanw/esbuild/issues/2460
|
// Work around https://github.com/evanw/esbuild/issues/2460
|
||||||
tsconfig: "./scripts/build/tsconfig.esbuild.json"
|
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
|
||||||
|
];
|
||||||
|
|
|
@ -21,8 +21,7 @@ import { Devs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import type { GroupDMChannelRecord, UserRecord } from "@vencord/discord-types";
|
import type { GroupDMChannelRecord, UserRecord } from "@vencord/discord-types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, UserStore, UserUtils } from "@webpack/common";
|
import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, useMemo, UserStore, UserUtils } from "@webpack/common";
|
||||||
import type { ReactElement } from "react";
|
|
||||||
|
|
||||||
const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel");
|
const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel");
|
||||||
|
|
||||||
|
@ -42,9 +41,27 @@ function getGroupDMName(channel: GroupDMChannelRecord) {
|
||||||
return names.join(", ");
|
return names.join(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const useMutualGroupDMs = (userId: string) => useMemo(
|
||||||
|
() => ChannelStore.getSortedPrivateChannels()
|
||||||
|
.filter((c): c is GroupDMChannelRecord => c.isGroupDM() && c.recipients.includes(userId)),
|
||||||
|
[userId]
|
||||||
|
);
|
||||||
|
|
||||||
|
const isBotOrMe = (user: UserRecord) => user.bot || user.id === UserStore.getCurrentUser()!.id;
|
||||||
|
|
||||||
|
function getMutualGDMCountText(user: UserRecord) {
|
||||||
|
let count = 0;
|
||||||
|
for (const channel of Object.values(ChannelStore.getMutablePrivateChannels()))
|
||||||
|
if (channel.isGroupDM() && channel.recipients.includes(user.id))
|
||||||
|
count++;
|
||||||
|
return `${count === 0 ? "No" : count} Mutual Group${count !== 1 ? "s" : ""}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const IS_PATCHED = Symbol("MutualGroupDMs.Patched");
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "MutualGroupDMs",
|
name: "MutualGroupDMs",
|
||||||
description: "Shows mutual group dms in profiles",
|
description: "Shows mutual group DMs in profiles",
|
||||||
authors: [Devs.amia],
|
authors: [Devs.amia],
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
|
@ -66,8 +83,8 @@ export default definePlugin({
|
||||||
find: ".MUTUAL_FRIENDS?(",
|
find: ".MUTUAL_FRIENDS?(",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /(?<=onItemSelect:\i,children:)(\i)\.map/,
|
match: /\i\.useEffect.{0,100}(\i)\[0\]\.section/,
|
||||||
replace: "[...$1, ...($self.isBotOrMe(arguments[0].user) ? [] : [{section:'MUTUAL_GDMS',text:$self.getMutualGDMCountText(arguments[0].user)}])].map"
|
replace: "$self.pushSection($1, arguments[0].user);$&"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
match: /\(0,\i\.jsx\)\(\i,\{items:\i,section:(\i)/,
|
match: /\(0,\i\.jsx\)\(\i,\{items:\i,section:(\i)/,
|
||||||
|
@ -77,21 +94,23 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
isBotOrMe: (user: UserRecord) => user.bot || user.id === UserStore.getCurrentUser()!.id,
|
isBotOrMe,
|
||||||
|
getMutualGDMCountText,
|
||||||
|
|
||||||
getMutualGDMCountText(user: UserRecord) {
|
pushSection(sections: any[] & { [IS_PATCHED]?: true; }, user: UserRecord) {
|
||||||
let count = 0;
|
if (isBotOrMe(user) || sections[IS_PATCHED]) return;
|
||||||
for (const channel of Object.values(ChannelStore.getMutablePrivateChannels()))
|
|
||||||
if (channel.isGroupDM() && channel.recipients.includes(user.id))
|
sections[IS_PATCHED] = true;
|
||||||
count++;
|
sections.push({
|
||||||
return `${count === 0 ? "No" : count} Mutual Group${count === 1 ? "" : "s"}`;
|
section: "MUTUAL_GDMS",
|
||||||
|
text: getMutualGDMCountText(user)
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
renderMutualGDMs: ErrorBoundary.wrap(({ user, onClose }: { user: UserRecord; onClose: () => void; }) => {
|
renderMutualGDMs: ErrorBoundary.wrap(({ user, onClose }: { user: UserRecord; onClose: () => void; }) => {
|
||||||
const entries: ReactElement[] = [];
|
const mutualGroupDMs = useMutualGroupDMs(user.id);
|
||||||
for (const channel of ChannelStore.getSortedPrivateChannels())
|
|
||||||
if (channel.isGroupDM() && channel.recipients.includes(user.id))
|
const entries = mutualGroupDMs.map(channel => (
|
||||||
entries.push(
|
|
||||||
<Clickable
|
<Clickable
|
||||||
className={ProfileListClasses.listRow}
|
className={ProfileListClasses.listRow}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -109,7 +128,7 @@ export default definePlugin({
|
||||||
<div className={GuildLabelClasses.guildNick}>{channel.recipients.length + 1} Members</div>
|
<div className={GuildLabelClasses.guildNick}>{channel.recipients.length + 1} Members</div>
|
||||||
</div>
|
</div>
|
||||||
</Clickable>
|
</Clickable>
|
||||||
);
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollerThin
|
<ScrollerThin
|
||||||
|
|
|
@ -24,13 +24,13 @@ const settings = definePluginSettings({
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "PictureInPicture",
|
name: "PictureInPicture",
|
||||||
description: "Adds picture in picture to videos (next to the Download button)",
|
description: "Adds picture in picture to videos (next to the Download button)",
|
||||||
authors: [Devs.Nobody],
|
authors: [Devs.Lumap],
|
||||||
settings,
|
settings,
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".nonMediaMosaicItem]",
|
find: ".removeMosaicItemHoverButton),",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.nonMediaMosaicItem\]:!(\i).{0,50}?children:\[(\S)/,
|
match: /\.nonMediaMosaicItem\]:!(\i).{0,50}?children:\[\S,(\S)/,
|
||||||
replace: "$&,$1&&$2&&$self.renderPiPButton(),"
|
replace: "$&,$1&&$2&&$self.renderPiPButton(),"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -33,10 +33,6 @@ export interface Dev {
|
||||||
* If you are fine with attribution but don't want the badge, add badge: false
|
* If you are fine with attribution but don't want the badge, add badge: false
|
||||||
*/
|
*/
|
||||||
export const Devs = /* #__PURE__*/ Object.freeze({
|
export const Devs = /* #__PURE__*/ Object.freeze({
|
||||||
Nobody: {
|
|
||||||
name: "Nobody",
|
|
||||||
id: 0n,
|
|
||||||
},
|
|
||||||
Ven: {
|
Ven: {
|
||||||
name: "Vee",
|
name: "Vee",
|
||||||
id: 343383572805058560n
|
id: 343383572805058560n
|
||||||
|
@ -545,7 +541,11 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
||||||
surgedevs: {
|
surgedevs: {
|
||||||
name: "Chloe",
|
name: "Chloe",
|
||||||
id: 1084592643784331324n
|
id: 1084592643784331324n
|
||||||
}
|
},
|
||||||
|
Lumap: {
|
||||||
|
name: "Lumap",
|
||||||
|
id: 585278686291427338n,
|
||||||
|
},
|
||||||
} satisfies Record<string, Dev>);
|
} satisfies Record<string, Dev>);
|
||||||
|
|
||||||
// iife so #__PURE__ works correctly
|
// iife so #__PURE__ works correctly
|
||||||
|
|
Loading…
Reference in a new issue