mirror of
https://github.com/Equicord/Equicord.git
synced 2025-02-18 22:28:51 -05:00
Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
commit
e4fcd54183
17 changed files with 86 additions and 133 deletions
|
@ -16,6 +16,7 @@ export default definePlugin({
|
|||
{
|
||||
find: '"sticker")',
|
||||
replacement: {
|
||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
||||
match: /return\((!)?\i\.\i(?:\|\||&&)(?=\(\i\.isDM.+?(\i)\.push)/,
|
||||
replace: (m, not, children) => not
|
||||
? `${m}(Vencord.Api.ChatButtons._injectButtons(${children},arguments[0]),true)&&`
|
||||
|
|
|
@ -37,12 +37,9 @@ export default definePlugin({
|
|||
{
|
||||
find: ".handleSendMessage,onResize",
|
||||
replacement: {
|
||||
// props.chatInputType...then((function(isMessageValid)... var parsedMessage = b.c.parse(channel,... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply);
|
||||
// Lookbehind: validateMessage)({openWarningPopout:..., type: i.props.chatInputType, content: t, stickers: r, ...}).then((function(isMessageValid)
|
||||
match: /(\{openWarningPopout:.{0,100}type:this.props.chatInputType.+?\.then\()(\i=>\{.+?let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptions\(\{.+?\}\);)(?<=\)\(({.+?})\)\.then.+?)/,
|
||||
// props.chatInputType...then((async function(isMessageValid)... var replyOptions = f.g.getSendMessageOptionsForReply(pendingReply); if(await Vencord.api...) return { shoudClear:true, shouldRefocus:true };
|
||||
replace: (_, rest1, rest2, parsedMessage, channel, replyOptions, extra) => "" +
|
||||
`${rest1}async ${rest2}` +
|
||||
// https://regex101.com/r/hBlXpl/1
|
||||
match: /let (\i)=\i\.\i\.parse\((\i),.+?let (\i)=\i\.\i\.getSendMessageOptions\(\{.+?\}\);(?<=\)\(({.+?})\)\.then.+?)/,
|
||||
replace: (m, parsedMessage, channel, replyOptions, extra) => m +
|
||||
`if(await Vencord.Api.MessageEvents._handlePreSend(${channel}.id,${parsedMessage},${extra},${replyOptions}))` +
|
||||
"return{shouldClear:false,shouldRefocus:true};"
|
||||
}
|
||||
|
@ -52,8 +49,7 @@ export default definePlugin({
|
|||
replacement: {
|
||||
match: /let\{id:\i}=(\i),{id:\i}=(\i);return \i\.useCallback\((\i)=>\{/,
|
||||
replace: (m, message, channel, event) =>
|
||||
// the message param is shadowed by the event param, so need to alias them
|
||||
`const vcMsg=${message},vcChan=${channel};${m}Vencord.Api.MessageEvents._handleClick(vcMsg, vcChan, ${event});`
|
||||
`const vcMsg=${message},vcChan=${channel};${m}Vencord.Api.MessageEvents._handleClick(vcMsg,vcChan,${event});`
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -64,6 +64,7 @@ export default definePlugin({
|
|||
replace: (_, sectionTypes, commaOrSemi, elements, element) => `${commaOrSemi} $self.addSettings(${elements}, ${element}, ${sectionTypes}) ${commaOrSemi}`
|
||||
},
|
||||
{
|
||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
||||
match: /({(?=.+?function (\i).{0,160}(\i)=\i\.useMemo.{0,140}return \i\.useMemo\(\(\)=>\i\(\3).+?(?:function\(\){return |\(\)=>))\2/,
|
||||
replace: (_, rest, settingsHook) => `${rest}$self.wrapSettingsHook(${settingsHook})`
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ export default definePlugin({
|
|||
{
|
||||
find: ".selectPreviousCommandOption(",
|
||||
replacement: {
|
||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
||||
match: /(?<=(\i)\.which(?:!==|===)\i\.\i.ENTER(\|\||&&)).{0,100}(\(0,\i\.\i\)\(\i\)).{0,100}(?=(?:\|\||&&)\(\i\.preventDefault)/,
|
||||
replace: (_, event, condition, codeblock) => `${condition === "||" ? "!" : ""}$self.shouldSubmit(${event},${codeblock})`
|
||||
}
|
||||
|
|
|
@ -264,6 +264,7 @@ export default definePlugin({
|
|||
},
|
||||
{
|
||||
// Disallow the emoji for premium locked if the intention doesn't allow it
|
||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
||||
match: /(!)?(\i\.\i\.canUseEmojisEverywhere\(\i\))/,
|
||||
replace: (m, not) => not
|
||||
? `(${m}&&!${IS_BYPASSEABLE_INTENTION})`
|
||||
|
|
|
@ -50,9 +50,9 @@ export default definePlugin({
|
|||
{
|
||||
find: "#{intl::FRIENDS_SECTION_ONLINE}",
|
||||
replacement: {
|
||||
match: /(\{id:\i\.\i\i)\.BLOCKED,.{0,150}(\i)\.item/,
|
||||
replace: "$1.IMPLICIT,show:!0,content:\"Implicit\",className:$2.item},$&"
|
||||
},
|
||||
match: /,{id:(\i\.\i)\.BLOCKED,show:.+?className:(\i\.item)/,
|
||||
replace: (rest, relationShipTypes, className) => `,{id:${relationShipTypes}.IMPLICIT,show:true,className:${className},content:"Implicit"}${rest}`
|
||||
}
|
||||
},
|
||||
// Sections content
|
||||
{
|
||||
|
|
|
@ -23,11 +23,11 @@ import definePlugin, { OptionType } from "@utils/types";
|
|||
import { useMemo } from "@webpack/common";
|
||||
|
||||
// Calculate a CSS color string based on the user ID
|
||||
function calculateNameColorForUser(id: string) {
|
||||
function calculateNameColorForUser(id?: string) {
|
||||
const { lightness } = settings.use(["lightness"]);
|
||||
const idHash = useMemo(() => h64(id), [id]);
|
||||
const idHash = useMemo(() => id ? h64(id) : null, [id]);
|
||||
|
||||
return `hsl(${idHash % 360n}, 100%, ${lightness}%)`;
|
||||
return idHash && `hsl(${idHash % 360n}, 100%, ${lightness}%)`;
|
||||
}
|
||||
|
||||
const settings = definePluginSettings({
|
||||
|
@ -70,16 +70,10 @@ export default definePlugin({
|
|||
|
||||
calculateNameColorForMessageContext(context: any) {
|
||||
const id = context?.message?.author?.id;
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
return calculateNameColorForUser(id);
|
||||
},
|
||||
calculateNameColorForListContext(context: any) {
|
||||
const id = context?.user?.id;
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
return calculateNameColorForUser(id);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -94,7 +94,7 @@ export default definePlugin({
|
|||
settings,
|
||||
|
||||
async start() {
|
||||
// TODO: Remove DataStore tags migration once enough time has passed
|
||||
// TODO(OptionType.CUSTOM Related): Remove DataStore tags migration once enough time has passed
|
||||
const oldTags = await DataStore.get<Tag[]>(DATA_KEY);
|
||||
if (oldTags != null) {
|
||||
// @ts-ignore
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Vencord, a modification for Discord's desktop app
|
||||
* Copyright (c) 2022 Vendicated and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { getUserSettingLazy } from "@api/UserSettings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
|
||||
const DisableStreamPreviews = getUserSettingLazy<boolean>("voiceAndVideo", "disableStreamPreviews")!;
|
||||
|
||||
// @TODO: Delete this plugin in the future
|
||||
export default definePlugin({
|
||||
name: "NoScreensharePreview",
|
||||
description: "Disables screenshare previews from being sent.",
|
||||
authors: [Devs.Nuckyz],
|
||||
|
||||
start() {
|
||||
if (!DisableStreamPreviews.getSetting()) {
|
||||
DisableStreamPreviews.updateSetting(true);
|
||||
}
|
||||
},
|
||||
|
||||
stop() {
|
||||
if (DisableStreamPreviews.getSetting()) {
|
||||
DisableStreamPreviews.updateSetting(false);
|
||||
}
|
||||
}
|
||||
});
|
|
@ -25,9 +25,9 @@ export default definePlugin({
|
|||
settings,
|
||||
patches: [
|
||||
{
|
||||
find: "_ensureAudio(){",
|
||||
find: "ensureAudio(){",
|
||||
replacement: {
|
||||
match: /(?=Math\.min\(\i\.\i\.getOutputVolume\(\)\/100)/,
|
||||
match: /(?=Math\.min\(\i\.\i\.getOutputVolume\(\)\/100)/g,
|
||||
replace: "$self.settings.store.notificationVolume/100*"
|
||||
},
|
||||
},
|
||||
|
|
|
@ -100,6 +100,7 @@ export default definePlugin({
|
|||
replace: "true"
|
||||
},
|
||||
{
|
||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
||||
match: /(!)?\(0,\i\.isDesktop\)\(\)/,
|
||||
replace: (_, not) => not ? "false" : "true"
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ export default definePlugin({
|
|||
find: "#{intl::ONBOARDING_CHANNEL_THRESHOLD_WARNING}",
|
||||
replacement: [
|
||||
{
|
||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
||||
match: /{(?:\i:(?:function\(\){return |\(\)=>)\i}?,?){2}}/,
|
||||
replace: m => m.replaceAll(canonicalizeMatch(/(function\(\){return |\(\)=>)\i/g), "$1()=>Promise.resolve(true)")
|
||||
}
|
||||
|
|
|
@ -155,7 +155,7 @@ export function moveChannel(channelId: string, direction: -1 | 1) {
|
|||
swapElementsInArray(category.channels, a, b);
|
||||
}
|
||||
|
||||
// TODO: Remove DataStore PinnedDms migration once enough time has passed
|
||||
// TODO(OptionType.CUSTOM Related): Remove DataStore PinnedDms migration once enough time has passed
|
||||
async function migrateData() {
|
||||
if (Settings.plugins.PinDMs.dmSectioncollapsed != null) {
|
||||
settings.store.dmSectionCollapsed = Settings.plugins.PinDMs.dmSectioncollapsed;
|
||||
|
|
|
@ -122,6 +122,7 @@ export default definePlugin({
|
|||
},
|
||||
{
|
||||
// Prevent Discord from trying to connect to hidden voice channels
|
||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
||||
match: /(?=(\|\||&&)\i\.\i\.selectVoiceChannel\((\i)\.id\))/,
|
||||
replace: (_, condition, channel) => condition === "||"
|
||||
? `||$self.isHiddenChannel(${channel})`
|
||||
|
@ -138,6 +139,7 @@ export default definePlugin({
|
|||
{
|
||||
find: ".AUDIENCE),{isSubscriptionGated",
|
||||
replacement: {
|
||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
||||
match: /(!)?(\i)\.isRoleSubscriptionTemplatePreviewChannel\(\)/,
|
||||
replace: (m, not, channel) => not
|
||||
? `${m}&&!$self.isHiddenChannel(${channel})`
|
||||
|
@ -204,6 +206,7 @@ export default definePlugin({
|
|||
},
|
||||
// Make voice channels also appear as muted if they are muted
|
||||
{
|
||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
||||
match: /(?<=\.wrapper:\i\.notInteractive,)(.+?)(if\()?(\i)(?:\)return |\?)(\i\.MUTED)/,
|
||||
replace: (_, otherClasses, isIf, isMuted, mutedClassExpression) => isIf
|
||||
? `${isMuted}?${mutedClassExpression}:"",${otherClasses}if(${isMuted})return ""`
|
||||
|
@ -222,6 +225,7 @@ export default definePlugin({
|
|||
predicate: () => settings.store.channelStyle !== ChannelStyle.Unread && settings.store.channelStyle !== ChannelStyle.MutedUnread,
|
||||
replacement: [
|
||||
{
|
||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
||||
match: /(?<=\.LOCKED(?:;if\(|:))(?<={channel:(\i).+?)/,
|
||||
replace: (_, channel) => `!$self.isHiddenChannel(${channel})&&`
|
||||
},
|
||||
|
|
|
@ -246,7 +246,7 @@ export default definePlugin({
|
|||
},
|
||||
|
||||
async start() {
|
||||
// TODO: Remove DataStore rules migrations once enough time has passed
|
||||
// TODO(OptionType.CUSTOM Related): Remove DataStore rules migrations once enough time has passed
|
||||
const oldStringRules = await DataStore.get<Rule[]>(STRING_RULES_KEY);
|
||||
if (oldStringRules != null) {
|
||||
settings.store.stringRules = oldStringRules;
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { patches } from "@plugins";
|
||||
import { WEBPACK_CHUNK } from "@utils/constants";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { canonicalizeReplacement } from "@utils/patches";
|
||||
|
@ -25,7 +24,8 @@ import { reporterData } from "debug/reporterData";
|
|||
import { WebpackInstance } from "discord-types/other";
|
||||
|
||||
import { traceFunction } from "../debug/Tracer";
|
||||
import { _initWebpack, beforeInitListeners, factoryListeners, moduleListeners, subscriptions, wreq } from ".";
|
||||
import { patches } from "../plugins";
|
||||
import { _initWebpack, _shouldIgnoreModule, beforeInitListeners, factoryListeners, moduleListeners, subscriptions, wreq } from ".";
|
||||
|
||||
const logger = new Logger("WebpackInterceptor", "#8caaee");
|
||||
|
||||
|
@ -174,35 +174,9 @@ function patchFactories(factories: Record<string, (module: any, exports: any, re
|
|||
if (!exports) return;
|
||||
|
||||
if (require.c) {
|
||||
let shouldMakeNonEnumerable = false;
|
||||
const shouldIgnoreModule = _shouldIgnoreModule(exports);
|
||||
|
||||
nonEnumerableChecking: {
|
||||
// There are (at the time of writing) 11 modules exporting the window,
|
||||
// and also modules exporting DOMTokenList, which breaks webpack finding
|
||||
// Make these non enumerable to improve search performance and avoid erros
|
||||
if (exports === window || exports[Symbol.toStringTag] === "DOMTokenList") {
|
||||
shouldMakeNonEnumerable = true;
|
||||
break nonEnumerableChecking;
|
||||
}
|
||||
|
||||
if (typeof exports !== "object") {
|
||||
break nonEnumerableChecking;
|
||||
}
|
||||
|
||||
if (exports.default === window || exports.default?.[Symbol.toStringTag] === "DOMTokenList") {
|
||||
shouldMakeNonEnumerable = true;
|
||||
break nonEnumerableChecking;
|
||||
}
|
||||
|
||||
for (const nested in exports) {
|
||||
if (exports[nested] === window || exports[nested]?.[Symbol.toStringTag] === "DOMTokenList") {
|
||||
shouldMakeNonEnumerable = true;
|
||||
break nonEnumerableChecking;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldMakeNonEnumerable) {
|
||||
if (shouldIgnoreModule) {
|
||||
Object.defineProperty(require.c, id, {
|
||||
value: require.c[id],
|
||||
enumerable: false,
|
||||
|
@ -227,17 +201,16 @@ function patchFactories(factories: Record<string, (module: any, exports: any, re
|
|||
if (exports && filter(exports)) {
|
||||
subscriptions.delete(filter);
|
||||
callback(exports, id);
|
||||
} else if (typeof exports === "object") {
|
||||
if (exports.default && filter(exports.default)) {
|
||||
}
|
||||
|
||||
if (typeof exports !== "object") {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const exportKey in exports) {
|
||||
if (exports[exportKey] && filter(exports[exportKey])) {
|
||||
subscriptions.delete(filter);
|
||||
callback(exports.default, id);
|
||||
} else {
|
||||
for (const nested in exports) {
|
||||
if (exports[nested] && filter(exports[nested])) {
|
||||
subscriptions.delete(filter);
|
||||
callback(exports[nested], id);
|
||||
}
|
||||
}
|
||||
callback(exports[exportKey], id);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
|
|
|
@ -71,13 +71,16 @@ export const filters = {
|
|||
componentByCode: (...code: CodeFilter): FilterFn => {
|
||||
const filter = filters.byCode(...code);
|
||||
return m => {
|
||||
if (filter(m)) return true;
|
||||
if (!m.$$typeof) return false;
|
||||
if (m.type)
|
||||
return m.type.render
|
||||
? filter(m.type.render) // memo + forwardRef
|
||||
: filter(m.type); // memo
|
||||
if (m.render) return filter(m.render); // forwardRef
|
||||
let inner = m;
|
||||
|
||||
while (inner != null) {
|
||||
if (filter(inner)) return true;
|
||||
else if (!inner.$$typeof) return false;
|
||||
else if (inner.type) inner = inner.type; // memos
|
||||
else if (inner.render) inner = inner.render; // forwardRefs
|
||||
else return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
@ -95,6 +98,38 @@ export function _initWebpack(webpackRequire: WebpackInstance) {
|
|||
cache = webpackRequire.c;
|
||||
}
|
||||
|
||||
// Credits to Zerebos for implementing this in BD, thus giving the idea for us to implement it too
|
||||
const TypedArray = Object.getPrototypeOf(Int8Array);
|
||||
|
||||
function _shouldIgnoreValue(value: any) {
|
||||
if (value == null) return true;
|
||||
if (value === window) return true;
|
||||
if (value === document || value === document.documentElement) return true;
|
||||
if (value[Symbol.toStringTag] === "DOMTokenList") return true;
|
||||
if (value instanceof TypedArray) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function _shouldIgnoreModule(exports: any) {
|
||||
if (_shouldIgnoreValue(exports)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof exports !== "object") {
|
||||
return false;
|
||||
}
|
||||
|
||||
let allNonEnumerable = true;
|
||||
for (const exportKey in exports) {
|
||||
if (!_shouldIgnoreValue(exports[exportKey])) {
|
||||
allNonEnumerable = false;
|
||||
}
|
||||
}
|
||||
|
||||
return allNonEnumerable;
|
||||
}
|
||||
|
||||
let devToolsOpen = false;
|
||||
if (IS_DEV && IS_DISCORD_DESKTOP) {
|
||||
// At this point in time, DiscordNative has not been exposed yet, so setImmediate is needed
|
||||
|
@ -121,7 +156,7 @@ export const find = traceFunction("find", function find(filter: FilterFn, { isIn
|
|||
|
||||
for (const key in cache) {
|
||||
const mod = cache[key];
|
||||
if (!mod.loaded || !mod?.exports) continue;
|
||||
if (!mod?.loaded || mod.exports == null) continue;
|
||||
|
||||
if (filter(mod.exports)) {
|
||||
return isWaitFor ? [mod.exports, key] : mod.exports;
|
||||
|
@ -129,11 +164,6 @@ export const find = traceFunction("find", function find(filter: FilterFn, { isIn
|
|||
|
||||
if (typeof mod.exports !== "object") continue;
|
||||
|
||||
if (mod.exports.default && filter(mod.exports.default)) {
|
||||
const found = mod.exports.default;
|
||||
return isWaitFor ? [found, key] : found;
|
||||
}
|
||||
|
||||
for (const nestedMod in mod.exports) {
|
||||
const nested = mod.exports[nestedMod];
|
||||
if (nested && filter(nested)) {
|
||||
|
@ -156,16 +186,15 @@ export function findAll(filter: FilterFn) {
|
|||
const ret = [] as any[];
|
||||
for (const key in cache) {
|
||||
const mod = cache[key];
|
||||
if (!mod.loaded || !mod?.exports) continue;
|
||||
if (!mod?.loaded || mod.exports == null) continue;
|
||||
|
||||
if (filter(mod.exports))
|
||||
ret.push(mod.exports);
|
||||
else if (typeof mod.exports !== "object")
|
||||
|
||||
if (typeof mod.exports !== "object")
|
||||
continue;
|
||||
|
||||
if (mod.exports.default && filter(mod.exports.default))
|
||||
ret.push(mod.exports.default);
|
||||
else for (const nestedMod in mod.exports) {
|
||||
for (const nestedMod in mod.exports) {
|
||||
const nested = mod.exports[nestedMod];
|
||||
if (nested && filter(nested)) ret.push(nested);
|
||||
}
|
||||
|
@ -204,7 +233,7 @@ export const findBulk = traceFunction("findBulk", function findBulk(...filterFns
|
|||
outer:
|
||||
for (const key in cache) {
|
||||
const mod = cache[key];
|
||||
if (!mod.loaded || !mod?.exports) continue;
|
||||
if (!mod?.loaded || mod.exports == null) continue;
|
||||
|
||||
for (let j = 0; j < length; j++) {
|
||||
const filter = filters[j];
|
||||
|
@ -221,13 +250,6 @@ export const findBulk = traceFunction("findBulk", function findBulk(...filterFns
|
|||
if (typeof mod.exports !== "object")
|
||||
continue;
|
||||
|
||||
if (mod.exports.default && filter(mod.exports.default)) {
|
||||
results[j] = mod.exports.default;
|
||||
filters[j] = undefined;
|
||||
if (++found === length) break outer;
|
||||
break;
|
||||
}
|
||||
|
||||
for (const nestedMod in mod.exports) {
|
||||
const nested = mod.exports[nestedMod];
|
||||
if (nested && filter(nested)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue