mirror of
https://github.com/Vendicated/Vencord.git
synced 2024-09-19 22:20:34 +00:00
Merge branch 'Vendicated:main' into main
This commit is contained in:
commit
73ca8dc776
20 changed files with 86 additions and 169 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "vencord",
|
"name": "vencord",
|
||||||
"private": "true",
|
"private": "true",
|
||||||
"version": "1.7.5",
|
"version": "1.7.7",
|
||||||
"description": "The cutest Discord client mod",
|
"description": "The cutest Discord client mod",
|
||||||
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
|
|
@ -299,9 +299,6 @@ function runTime(token: string) {
|
||||||
delete patch.predicate;
|
delete patch.predicate;
|
||||||
delete patch.group;
|
delete patch.group;
|
||||||
|
|
||||||
if (!Array.isArray(patch.find))
|
|
||||||
patch.find = [patch.find];
|
|
||||||
|
|
||||||
if (!Array.isArray(patch.replacement))
|
if (!Array.isArray(patch.replacement))
|
||||||
patch.replacement = [patch.replacement];
|
patch.replacement = [patch.replacement];
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,8 @@ if (IS_DEV) {
|
||||||
var differ = require("diff") as typeof import("diff");
|
var differ = require("diff") as typeof import("diff");
|
||||||
}
|
}
|
||||||
|
|
||||||
const findCandidates = debounce(function ({ finds, setModule, setError }) {
|
const findCandidates = debounce(function ({ find, setModule, setError }) {
|
||||||
const candidates = search(...finds);
|
const candidates = search(find);
|
||||||
const keys = Object.keys(candidates);
|
const keys = Object.keys(candidates);
|
||||||
const len = keys.length;
|
const len = keys.length;
|
||||||
if (len === 0)
|
if (len === 0)
|
||||||
|
@ -180,8 +180,7 @@ function ReplacementInput({ replacement, setReplacement, replacementError }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* FormTitle adds a class if className is not set, so we set it to an empty string to prevent that */}
|
<Forms.FormTitle>replacement</Forms.FormTitle>
|
||||||
<Forms.FormTitle className="">replacement</Forms.FormTitle>
|
|
||||||
<TextInput
|
<TextInput
|
||||||
value={replacement?.toString()}
|
value={replacement?.toString()}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
@ -189,7 +188,7 @@ function ReplacementInput({ replacement, setReplacement, replacementError }) {
|
||||||
/>
|
/>
|
||||||
{!isFunc && (
|
{!isFunc && (
|
||||||
<div className="vc-text-selectable">
|
<div className="vc-text-selectable">
|
||||||
<Forms.FormTitle className={Margins.top8}>Cheat Sheet</Forms.FormTitle>
|
<Forms.FormTitle>Cheat Sheet</Forms.FormTitle>
|
||||||
{Object.entries({
|
{Object.entries({
|
||||||
"\\i": "Special regex escape sequence that matches identifiers (varnames, classnames, etc.)",
|
"\\i": "Special regex escape sequence that matches identifiers (varnames, classnames, etc.)",
|
||||||
"$$": "Insert a $",
|
"$$": "Insert a $",
|
||||||
|
@ -221,12 +220,11 @@ function ReplacementInput({ replacement, setReplacement, replacementError }) {
|
||||||
|
|
||||||
interface FullPatchInputProps {
|
interface FullPatchInputProps {
|
||||||
setFind(v: string): void;
|
setFind(v: string): void;
|
||||||
setFinds(v: string[]): void;
|
|
||||||
setMatch(v: string): void;
|
setMatch(v: string): void;
|
||||||
setReplacement(v: string | ReplaceFn): void;
|
setReplacement(v: string | ReplaceFn): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function FullPatchInput({ setFind, setFinds, setMatch, setReplacement }: FullPatchInputProps) {
|
function FullPatchInput({ setFind, setMatch, setReplacement }: FullPatchInputProps) {
|
||||||
const [fullPatch, setFullPatch] = React.useState<string>("");
|
const [fullPatch, setFullPatch] = React.useState<string>("");
|
||||||
const [fullPatchError, setFullPatchError] = React.useState<string>("");
|
const [fullPatchError, setFullPatchError] = React.useState<string>("");
|
||||||
|
|
||||||
|
@ -258,8 +256,7 @@ function FullPatchInput({ setFind, setFinds, setMatch, setReplacement }: FullPat
|
||||||
if (!parsed.replacement.match) throw new Error("No 'replacement.match' field");
|
if (!parsed.replacement.match) throw new Error("No 'replacement.match' field");
|
||||||
if (!parsed.replacement.replace) throw new Error("No 'replacement.replace' field");
|
if (!parsed.replacement.replace) throw new Error("No 'replacement.replace' field");
|
||||||
|
|
||||||
setFind(JSON.stringify(parsed.find));
|
setFind(parsed.find);
|
||||||
setFinds(parsed.find instanceof Array ? parsed.find : [parsed.find]);
|
|
||||||
setMatch(parsed.replacement.match instanceof RegExp ? parsed.replacement.match.source : parsed.replacement.match);
|
setMatch(parsed.replacement.match instanceof RegExp ? parsed.replacement.match.source : parsed.replacement.match);
|
||||||
setReplacement(parsed.replacement.replace);
|
setReplacement(parsed.replacement.replace);
|
||||||
setFullPatchError("");
|
setFullPatchError("");
|
||||||
|
@ -269,7 +266,7 @@ function FullPatchInput({ setFind, setFinds, setMatch, setReplacement }: FullPat
|
||||||
}
|
}
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<Forms.FormText className={Margins.bottom8}>Paste your full JSON patch here to fill out the fields</Forms.FormText>
|
<Forms.FormText>Paste your full JSON patch here to fill out the fields</Forms.FormText>
|
||||||
<TextArea value={fullPatch} onChange={setFullPatch} onBlur={update} />
|
<TextArea value={fullPatch} onChange={setFullPatch} onBlur={update} />
|
||||||
{fullPatchError !== "" && <Forms.FormText style={{ color: "var(--text-danger)" }}>{fullPatchError}</Forms.FormText>}
|
{fullPatchError !== "" && <Forms.FormText style={{ color: "var(--text-danger)" }}>{fullPatchError}</Forms.FormText>}
|
||||||
</>;
|
</>;
|
||||||
|
@ -277,7 +274,6 @@ function FullPatchInput({ setFind, setFinds, setMatch, setReplacement }: FullPat
|
||||||
|
|
||||||
function PatchHelper() {
|
function PatchHelper() {
|
||||||
const [find, setFind] = React.useState<string>("");
|
const [find, setFind] = React.useState<string>("");
|
||||||
const [finds, setFinds] = React.useState<string[]>([]);
|
|
||||||
const [match, setMatch] = React.useState<string>("");
|
const [match, setMatch] = React.useState<string>("");
|
||||||
const [replacement, setReplacement] = React.useState<string | ReplaceFn>("");
|
const [replacement, setReplacement] = React.useState<string | ReplaceFn>("");
|
||||||
|
|
||||||
|
@ -289,39 +285,20 @@ function PatchHelper() {
|
||||||
const code = React.useMemo(() => {
|
const code = React.useMemo(() => {
|
||||||
return `
|
return `
|
||||||
{
|
{
|
||||||
find: ${finds.length > 1 ? `[${finds.map(f => JSON.stringify(f)).join(", ")}]` : finds.length > 0 ? JSON.stringify(finds[0]) : "[]"},
|
find: ${JSON.stringify(find)},
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /${match.replace(/(?<!\\)\//g, "\\/")}/,
|
match: /${match.replace(/(?<!\\)\//g, "\\/")}/,
|
||||||
replace: ${typeof replacement === "function" ? replacement.toString() : JSON.stringify(replacement)}
|
replace: ${typeof replacement === "function" ? replacement.toString() : JSON.stringify(replacement)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`.trim();
|
`.trim();
|
||||||
}, [finds, match, replacement]);
|
}, [find, match, replacement]);
|
||||||
|
|
||||||
function onFindChange(v: string) {
|
function onFindChange(v: string) {
|
||||||
setFindError(void 0);
|
setFindError(void 0);
|
||||||
setFind(v);
|
setFind(v);
|
||||||
}
|
if (v.length) {
|
||||||
|
findCandidates({ find: v, setModule, setError: setFindError });
|
||||||
function onFindBlur() {
|
|
||||||
let finds = [] as string[];
|
|
||||||
const findArrayMatch = find.match(/^\[.*\]$/);
|
|
||||||
|
|
||||||
if (findArrayMatch) {
|
|
||||||
try {
|
|
||||||
const rawFinds = (0, eval)(`(${find})`);
|
|
||||||
finds = rawFinds instanceof Array ? rawFinds : [rawFinds];
|
|
||||||
} catch (e) {
|
|
||||||
setFindError((e as Error).message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (find.length) {
|
|
||||||
finds = [find];
|
|
||||||
}
|
|
||||||
|
|
||||||
setFinds(finds);
|
|
||||||
if (finds.length) {
|
|
||||||
findCandidates({ finds, setModule, setError: setFindError });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,21 +317,19 @@ function PatchHelper() {
|
||||||
<Forms.FormTitle>full patch</Forms.FormTitle>
|
<Forms.FormTitle>full patch</Forms.FormTitle>
|
||||||
<FullPatchInput
|
<FullPatchInput
|
||||||
setFind={onFindChange}
|
setFind={onFindChange}
|
||||||
setFinds={setFinds}
|
|
||||||
setMatch={onMatchChange}
|
setMatch={onMatchChange}
|
||||||
setReplacement={setReplacement}
|
setReplacement={setReplacement}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Forms.FormTitle className={Margins.top8}>find</Forms.FormTitle>
|
<Forms.FormTitle>find</Forms.FormTitle>
|
||||||
<TextInput
|
<TextInput
|
||||||
type="text"
|
type="text"
|
||||||
value={find}
|
value={find}
|
||||||
onChange={onFindChange}
|
onChange={onFindChange}
|
||||||
onBlur={onFindBlur}
|
|
||||||
error={findError}
|
error={findError}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Forms.FormTitle className={Margins.top8}>match</Forms.FormTitle>
|
<Forms.FormTitle>match</Forms.FormTitle>
|
||||||
<CheckedTextInput
|
<CheckedTextInput
|
||||||
value={match}
|
value={match}
|
||||||
onChange={onMatchChange}
|
onChange={onMatchChange}
|
||||||
|
@ -367,7 +342,6 @@ function PatchHelper() {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className={Margins.top8} />
|
|
||||||
<ReplacementInput
|
<ReplacementInput
|
||||||
replacement={replacement}
|
replacement={replacement}
|
||||||
setReplacement={setReplacement}
|
setReplacement={setReplacement}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import { ApplicationAssetUtils, FluxDispatcher, Forms, GuildStore, React, Select
|
||||||
|
|
||||||
const ActivityComponent = findComponentByCodeLazy("onOpenGameProfile");
|
const ActivityComponent = findComponentByCodeLazy("onOpenGameProfile");
|
||||||
const ActivityClassName = findByPropsLazy("activity", "buttonColor");
|
const ActivityClassName = findByPropsLazy("activity", "buttonColor");
|
||||||
const Colors = findByPropsLazy("profileColors");
|
|
||||||
|
|
||||||
async function getApplicationAsset(key: string): Promise<string> {
|
async function getApplicationAsset(key: string): Promise<string> {
|
||||||
if (/https?:\/\/(cdn|media)\.discordapp\.(com|net)\/attachments\//.test(key)) return "mp:" + key.replace(/https?:\/\/(cdn|media)\.discordapp\.(com|net)\//, "");
|
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 <Link href="https://imgur.com">Imgur</Link> and get the image link by right-clicking the image and select "Copy image address".
|
If you want to use image link, download your image and reupload the image to <Link href="https://imgur.com">Imgur</Link> and get the image link by right-clicking the image and select "Copy image address".
|
||||||
</Forms.FormText>
|
</Forms.FormText>
|
||||||
<Forms.FormDivider />
|
<Forms.FormDivider />
|
||||||
<div style={{ width: "284px" }} className={Colors.profileColors}>
|
<div style={{ width: "284px" }}>
|
||||||
{activity[0] && <ActivityComponent activity={activity[0]} className={ActivityClassName.activity} channelId={SelectedChannelStore.getChannelId()}
|
{activity[0] && <ActivityComponent activity={activity[0]} className={ActivityClassName.activity} channelId={SelectedChannelStore.getChannelId()}
|
||||||
guild={GuildStore.getGuild(SelectedGuildStore.getLastSelectedGuildId())}
|
guild={GuildStore.getGuild(SelectedGuildStore.getLastSelectedGuildId())}
|
||||||
application={{ id: settings.store.appID }}
|
application={{ id: settings.store.appID }}
|
||||||
|
|
|
@ -83,6 +83,6 @@ export default definePlugin({
|
||||||
if (!aIsFavorite && bIsFavorite) return 1;
|
if (!aIsFavorite && bIsFavorite) return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}).slice(0, query.results.emojis.sliceTo ?? 10);
|
}).slice(0, query.results.emojis.sliceTo ?? Infinity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -79,8 +79,6 @@ for (const p of pluginsValues) {
|
||||||
if (p.patches && isPluginEnabled(p.name)) {
|
if (p.patches && isPluginEnabled(p.name)) {
|
||||||
for (const patch of p.patches) {
|
for (const patch of p.patches) {
|
||||||
patch.plugin = p.name;
|
patch.plugin = p.name;
|
||||||
if (!Array.isArray(patch.find))
|
|
||||||
patch.find = [patch.find];
|
|
||||||
if (!Array.isArray(patch.replacement))
|
if (!Array.isArray(patch.replacement))
|
||||||
patch.replacement = [patch.replacement];
|
patch.replacement = [patch.replacement];
|
||||||
patches.push(patch);
|
patches.push(patch);
|
||||||
|
|
|
@ -337,12 +337,12 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
// Attachment renderer
|
// Attachment renderer
|
||||||
// Module 96063
|
// Module 96063
|
||||||
find: ".removeAttachmentHoverButton",
|
find: ".removeMosaicItemHoverButton",
|
||||||
group: true,
|
group: true,
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /(className:\i,attachment:\i),/,
|
match: /(className:\i,item:\i),/,
|
||||||
replace: "$1,attachment: {deleted},"
|
replace: "$1,item: deleted,"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
match: /\[\i\.obscured\]:.+?,/,
|
match: /\[\i\.obscured\]:.+?,/,
|
||||||
|
|
|
@ -5,15 +5,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { disableStyle, enableStyle } from "@api/Styles";
|
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
|
||||||
import style from "./styles.css?managed";
|
|
||||||
|
|
||||||
const MAX_WIDTH = 550;
|
|
||||||
const MAX_HEIGHT = 350;
|
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
inlineVideo: {
|
inlineVideo: {
|
||||||
description: "Play videos without carousel modal",
|
description: "Play videos without carousel modal",
|
||||||
|
@ -33,15 +27,11 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".oneByTwoLayoutThreeGrid",
|
find: "isGroupableMedia:function()",
|
||||||
replacement: [{
|
replacement: {
|
||||||
match: /mediaLayoutType:\i\.\i\.MOSAIC/,
|
match: /=>"IMAGE"===\i\|\|"VIDEO"===\i;/,
|
||||||
replace: "mediaLayoutType:'RESPONSIVE'",
|
replace: "=>false;"
|
||||||
},
|
}
|
||||||
{
|
|
||||||
match: /null!==\(\i=\i\.get\(\i\)\)&&void 0!==\i\?\i:"INVALID"/,
|
|
||||||
replace: '"INVALID"',
|
|
||||||
}]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: "renderAttachments(",
|
find: "renderAttachments(",
|
||||||
|
@ -51,52 +41,5 @@ export default definePlugin({
|
||||||
replace: "$&$1.content_type?.startsWith('image/')&&"
|
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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
[class^="nonMediaAttachmentsContainer_"] [class*="messageAttachment_"] {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
[class^="nonMediaAttachmentsContainer_"],
|
|
||||||
[class^="nonMediaAttachmentItem_"]:has([class^="messageAttachment_"][style^="max-width"]) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
|
@ -10,7 +10,7 @@ import { definePluginSettings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { React, Tooltip } from "@webpack/common";
|
import { Tooltip } from "@webpack/common";
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
loop: {
|
loop: {
|
||||||
|
@ -28,9 +28,9 @@ export default definePlugin({
|
||||||
settings,
|
settings,
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".nonMediaAttachment]",
|
find: ".nonMediaMosaicItem]",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.nonMediaAttachment\]:!(\i).{0,10}children:\[(\S)/,
|
match: /\.nonMediaMosaicItem\]:!(\i).{0,10}children:\[(\S)/,
|
||||||
replace: "$&,$1&&$2&&$self.renderPiPButton(),"
|
replace: "$&,$1&&$2&&$self.renderPiPButton(),"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -36,25 +36,24 @@ export default definePlugin({
|
||||||
authors: [Devs.Tyman, Devs.TheKodeToad, Devs.Ven],
|
authors: [Devs.Tyman, Devs.TheKodeToad, Devs.Ven],
|
||||||
description: "Adds pronouns to user messages using pronoundb",
|
description: "Adds pronouns to user messages using pronoundb",
|
||||||
patches: [
|
patches: [
|
||||||
// Add next to username (compact mode)
|
|
||||||
{
|
{
|
||||||
find: "showCommunicationDisabledStyles",
|
find: "showCommunicationDisabledStyles",
|
||||||
replacement: {
|
replacement: [
|
||||||
match: /("span",{id:\i,className:\i,children:\i}\))/,
|
// Add next to username (compact mode)
|
||||||
replace: "$1, $self.CompactPronounsChatComponentWrapper(arguments[0])"
|
{
|
||||||
}
|
match: /("span",{id:\i,className:\i,children:\i}\))/,
|
||||||
},
|
replace: "$1, $self.CompactPronounsChatComponentWrapper(arguments[0])"
|
||||||
// Patch the chat timestamp element (normal mode)
|
},
|
||||||
{
|
// Patch the chat timestamp element (normal mode)
|
||||||
find: "showCommunicationDisabledStyles",
|
{
|
||||||
replacement: {
|
match: /(?<=return\s*\(0,\i\.jsxs?\)\(.+!\i&&)(\(0,\i.jsxs?\)\(.+?\{.+?\}\))/,
|
||||||
match: /(?<=return\s*\(0,\i\.jsxs?\)\(.+!\i&&)(\(0,\i.jsxs?\)\(.+?\{.+?\}\))/,
|
replace: "[$1, $self.PronounsChatComponentWrapper(arguments[0])]"
|
||||||
replace: "[$1, $self.PronounsChatComponentWrapper(arguments[0])]"
|
}
|
||||||
}
|
]
|
||||||
},
|
},
|
||||||
// Patch the profile popout username header to use our pronoun hook instead of Discord's pronouns
|
// Patch the profile popout username header to use our pronoun hook instead of Discord's pronouns
|
||||||
{
|
{
|
||||||
find: ".userTagNoNickname",
|
find: ".pronouns,children",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /{user:(\i),[^}]*,pronouns:(\i),[^}]*}=\i;/,
|
match: /{user:(\i),[^}]*,pronouns:(\i),[^}]*}=\i;/,
|
||||||
|
|
|
@ -94,7 +94,7 @@ export default definePlugin({
|
||||||
find: "renderPrioritySpeaker",
|
find: "renderPrioritySpeaker",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /renderName\(\).{0,100}speaking:.{50,100}jsx.{5,10}{/,
|
match: /renderName\(\).{0,100}speaking:.{50,150}"div",{/,
|
||||||
replace: "$&...$self.getVoiceProps(this.props),"
|
replace: "$&...$self.getVoiceProps(this.props),"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -35,7 +35,7 @@ const Section = findComponentByCodeLazy(".lastSection", "children:");
|
||||||
const ThemeStore = findStoreLazy("ThemeStore");
|
const ThemeStore = findStoreLazy("ThemeStore");
|
||||||
const platformHooks: { useLegacyPlatformType(platform: string): string; } = findByPropsLazy("useLegacyPlatformType");
|
const platformHooks: { useLegacyPlatformType(platform: string): string; } = findByPropsLazy("useLegacyPlatformType");
|
||||||
const platforms: { get(type: string): ConnectionPlatform; } = findByPropsLazy("isSupported", "getByUrl");
|
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 {
|
const enum Spacing {
|
||||||
COMPACT,
|
COMPACT,
|
||||||
|
|
|
@ -49,7 +49,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: ".useCanSeeRemixBadge)",
|
find: ".useCanSeeRemixBadge)",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=onContextMenu:\i,children:).*?\}/,
|
match: /(?<=onContextMenu:\i,children:).*?\)}/,
|
||||||
replace: "$self.renderUsername(arguments[0])}"
|
replace: "$self.renderUsername(arguments[0])}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
import "./spotifyStyles.css";
|
import "./spotifyStyles.css";
|
||||||
|
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
|
||||||
import { Flex } from "@components/Flex";
|
import { Flex } from "@components/Flex";
|
||||||
import { ImageIcon, LinkIcon, OpenExternalIcon } from "@components/Icons";
|
import { ImageIcon, LinkIcon, OpenExternalIcon } from "@components/Icons";
|
||||||
import { debounce } from "@shared/debounce";
|
import { debounce } from "@shared/debounce";
|
||||||
|
@ -376,17 +375,10 @@ export function Player() {
|
||||||
} as React.CSSProperties;
|
} as React.CSSProperties;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary fallback={() => (
|
<div id={cl("player")} style={exportTrackImageStyle}>
|
||||||
<div className="vc-spotify-fallback">
|
<Info track={track} />
|
||||||
<p>Failed to render Spotify Modal :(</p>
|
<SeekBar />
|
||||||
<p >Check the console for errors</p>
|
<Controls />
|
||||||
</div>
|
</div>
|
||||||
)}>
|
|
||||||
<div id={cl("player")} style={exportTrackImageStyle}>
|
|
||||||
<Info track={track} />
|
|
||||||
<SeekBar />
|
|
||||||
<Controls />
|
|
||||||
</div>
|
|
||||||
</ErrorBoundary>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
import { Settings } from "@api/Settings";
|
import { Settings } from "@api/Settings";
|
||||||
import { disableStyle, enableStyle } from "@api/Styles";
|
import { disableStyle, enableStyle } from "@api/Styles";
|
||||||
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
|
||||||
|
@ -49,10 +50,10 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: "showTaglessAccountPanel:",
|
find: "showTaglessAccountPanel:",
|
||||||
replacement: {
|
replacement: {
|
||||||
// return React.createElement(AccountPanel, { ..., showTaglessAccountPanel: blah })
|
// react.jsx)(AccountPanel, { ..., showTaglessAccountPanel: blah })
|
||||||
match: /return ?(.{0,30}\(.{1,3},\{[^}]+?,showTaglessAccountPanel:.+?\}\))/,
|
match: /(?<=\i\.jsxs?\)\()(\i),{(?=[^}]*?showTaglessAccountPanel:)/,
|
||||||
// return [Player, Panel]
|
// react.jsx(WrapperComponent, { VencordOriginal: AccountPanel, ...
|
||||||
replace: "return [$self.renderPlayer(),$1]"
|
replace: "$self.PanelWrapper,{VencordOriginal:$1,"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -78,6 +79,25 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
start: () => toggleHoverControls(Settings.plugins.SpotifyControls.hoverControls),
|
start: () => toggleHoverControls(Settings.plugins.SpotifyControls.hoverControls),
|
||||||
renderPlayer: () => <Player />
|
|
||||||
|
PanelWrapper({ VencordOriginal, ...props }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ErrorBoundary
|
||||||
|
fallback={() => (
|
||||||
|
<div className="vc-spotify-fallback">
|
||||||
|
<p>Failed to render Spotify Modal :(</p>
|
||||||
|
<p >Check the console for errors</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Player />
|
||||||
|
</ErrorBoundary>
|
||||||
|
|
||||||
|
<VencordOriginal {...props} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -174,7 +174,7 @@ export default definePlugin({
|
||||||
find: ".NITRO_BANNER,",
|
find: ".NITRO_BANNER,",
|
||||||
replacement: {
|
replacement: {
|
||||||
// style: { backgroundImage: shouldShowBanner ? "url(".concat(bannerUrl,
|
// style: { backgroundImage: shouldShowBanner ? "url(".concat(bannerUrl,
|
||||||
match: /style:\{(?=backgroundImage:(\i)\?"url\("\.concat\((\i),)/,
|
match: /style:\{(?=backgroundImage:(null!=\i)\?"url\("\.concat\((\i),)/,
|
||||||
replace:
|
replace:
|
||||||
// onClick: () => shouldShowBanner && ev.target.style.backgroundImage && openImage(bannerUrl), style: { cursor: shouldShowBanner ? "pointer" : void 0,
|
// 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,'
|
'onClick:ev=>$1&&ev.target.style.backgroundImage&&$self.openImage($2),style:{cursor:$1?"pointer":void 0,'
|
||||||
|
|
|
@ -36,7 +36,7 @@ export interface PatchReplacement {
|
||||||
|
|
||||||
export interface Patch {
|
export interface Patch {
|
||||||
plugin: string;
|
plugin: string;
|
||||||
find: string | string[];
|
find: string;
|
||||||
replacement: PatchReplacement | PatchReplacement[];
|
replacement: PatchReplacement | PatchReplacement[];
|
||||||
/** Whether this patch should apply to multiple modules */
|
/** Whether this patch should apply to multiple modules */
|
||||||
all?: boolean;
|
all?: boolean;
|
||||||
|
|
|
@ -186,8 +186,7 @@ function patchFactories(factories: Record<string | number, (module: { exports: a
|
||||||
const executePatch = traceFunction(`patch by ${patch.plugin}`, (match: string | RegExp, replace: string) => code.replace(match, replace));
|
const executePatch = traceFunction(`patch by ${patch.plugin}`, (match: string | RegExp, replace: string) => code.replace(match, replace));
|
||||||
if (patch.predicate && !patch.predicate()) continue;
|
if (patch.predicate && !patch.predicate()) continue;
|
||||||
|
|
||||||
// we change all patch.find to array in plugins/index
|
if (code.includes(patch.find)) {
|
||||||
if ((patch.find as string[]).every(f => code.includes(f))) {
|
|
||||||
patchedBy.add(patch.plugin);
|
patchedBy.add(patch.plugin);
|
||||||
|
|
||||||
const previousMod = mod;
|
const previousMod = mod;
|
||||||
|
|
|
@ -406,13 +406,15 @@ export function findExportedComponentLazy<T extends object = any>(...props: stri
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DefaultExtractAndLoadChunksRegex = /(?:Promise\.all\((\[\i\.\i\(".+?"\).+?\])\)|Promise\.resolve\(\)).then\(\i\.bind\(\i,"(.+?)"\)\)/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract and load chunks using their entry point
|
* 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 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
|
* @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
|
* @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);
|
const module = findModuleFactory(...code);
|
||||||
if (!module) {
|
if (!module) {
|
||||||
const err = new Error("extractAndLoadChunks: Couldn't find module factory");
|
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;
|
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");
|
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);
|
logger.warn(err, "Code:", code, "Matcher:", matcher);
|
||||||
|
|
||||||
|
@ -445,9 +447,11 @@ export async function extractAndLoadChunks(code: string[], matcher: RegExp = /Pr
|
||||||
return;
|
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);
|
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
|
* @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
|
* @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]]);
|
if (IS_DEV) lazyWebpackSearchHistory.push(["extractAndLoadChunks", [code, matcher]]);
|
||||||
|
|
||||||
return () => extractAndLoadChunks(code, matcher);
|
return () => extractAndLoadChunks(code, matcher);
|
||||||
|
|
Loading…
Reference in a new issue