Improvements, changes and fixes (#611)
This commit is contained in:
parent
5873bde6a6
commit
0fb79b763d
|
@ -23,13 +23,13 @@ import type { ReactElement } from "react";
|
|||
* @param children The rendered context menu elements
|
||||
* @param args Any arguments passed into making the context menu, like the guild, channel, user or message for example
|
||||
*/
|
||||
export type NavContextMenuPatchCallback = (children: Array<React.ReactElement>, args?: Array<any>) => void;
|
||||
export type NavContextMenuPatchCallback = (children: Array<React.ReactElement>, ...args: Array<any>) => void;
|
||||
/**
|
||||
* @param The navId of the context menu being patched
|
||||
* @param children The rendered context menu elements
|
||||
* @param args Any arguments passed into making the context menu, like the guild, channel, user or message for example
|
||||
*/
|
||||
export type GlobalContextMenuPatchCallback = (navId: string, children: Array<React.ReactElement>, args?: Array<any>) => void;
|
||||
export type GlobalContextMenuPatchCallback = (navId: string, children: Array<React.ReactElement>, ...args: Array<any>) => void;
|
||||
|
||||
const ContextMenuLogger = new Logger("ContextMenu");
|
||||
|
||||
|
@ -119,12 +119,13 @@ interface ContextMenuProps {
|
|||
}
|
||||
|
||||
export function _patchContextMenu(props: ContextMenuProps) {
|
||||
props.contextMenuApiArguments ??= [];
|
||||
const contextMenuPatches = navPatches.get(props.navId);
|
||||
|
||||
if (contextMenuPatches) {
|
||||
for (const patch of contextMenuPatches) {
|
||||
try {
|
||||
patch(props.children, props.contextMenuApiArguments);
|
||||
patch(props.children, ...props.contextMenuApiArguments);
|
||||
} catch (err) {
|
||||
ContextMenuLogger.error(`Patch for ${props.navId} errored,`, err);
|
||||
}
|
||||
|
@ -133,7 +134,7 @@ export function _patchContextMenu(props: ContextMenuProps) {
|
|||
|
||||
for (const patch of globalPatches) {
|
||||
try {
|
||||
patch(props.navId, props.children, props.contextMenuApiArguments);
|
||||
patch(props.navId, props.children, ...props.contextMenuApiArguments);
|
||||
} catch (err) {
|
||||
ContextMenuLogger.error("Global patch errored,", err);
|
||||
}
|
||||
|
|
|
@ -18,9 +18,28 @@
|
|||
|
||||
import { Settings } from "@api/settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import definePlugin, { type PatchReplacement } from "@utils/types";
|
||||
import { addListener, removeListener } from "@webpack";
|
||||
|
||||
/**
|
||||
* The last var name corresponding to the Context Menu API (Discord, not ours) module
|
||||
*/
|
||||
let lastVarName = "";
|
||||
|
||||
/**
|
||||
* @param target The patch replacement object
|
||||
* @param exportKey The key exporting the build Context Menu component function
|
||||
*/
|
||||
function makeReplacementProxy(target: PatchReplacement, exportKey: string) {
|
||||
return new Proxy(target, {
|
||||
get(_, p) {
|
||||
if (p === "match") return RegExp(`${exportKey},{(?<=${lastVarName}\\.${exportKey},{)`, "g");
|
||||
// @ts-expect-error
|
||||
return Reflect.get(...arguments);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function listener(exports: any, id: number) {
|
||||
if (!Settings.plugins.ContextMenuAPI.enabled) return removeListener(listener);
|
||||
|
||||
|
@ -37,13 +56,24 @@ function listener(exports: any, id: number) {
|
|||
all: true,
|
||||
noWarn: true,
|
||||
find: "navId:",
|
||||
replacement: [{
|
||||
match: RegExp(`${id}(?<=(\\i)=.+?).+$`),
|
||||
replace: (code, varName) => {
|
||||
const regex = RegExp(`${key},{(?<=${varName}\\.${key},{)`, "g");
|
||||
return code.replace(regex, "$&contextMenuApiArguments:arguments,");
|
||||
replacement: [
|
||||
{
|
||||
// Set the lastVarName for our proxy to use
|
||||
match: RegExp(`${id}(?<=(\\i)=.+?)`),
|
||||
replace: (id, varName) => {
|
||||
lastVarName = varName;
|
||||
return id;
|
||||
}
|
||||
}]
|
||||
},
|
||||
/**
|
||||
* We are using a proxy here to utilize the whole code the patcher gives us, instead of matching the entire module (which is super slow)
|
||||
* Our proxy returns the corresponding match for that module utilizing lastVarName, which is set by the patch before
|
||||
*/
|
||||
makeReplacementProxy({
|
||||
match: "", // Needed to canonicalizeDescriptor
|
||||
replace: "$&contextMenuApiArguments:arguments,",
|
||||
}, key)
|
||||
]
|
||||
});
|
||||
|
||||
removeListener(listener);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { addContextMenuPatch } from "@api/ContextMenu";
|
||||
import { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
|
||||
import { showNotification } from "@api/Notifications";
|
||||
import { Devs } from "@utils/constants";
|
||||
import Logger from "@utils/Logger";
|
||||
|
@ -221,15 +221,7 @@ function initWs(isManual = false) {
|
|||
});
|
||||
}
|
||||
|
||||
export default definePlugin({
|
||||
name: "DevCompanion",
|
||||
description: "Dev Companion Plugin",
|
||||
authors: [Devs.Ven],
|
||||
dependencies: ["ContextMenuAPI"],
|
||||
|
||||
start() {
|
||||
initWs();
|
||||
addContextMenuPatch("user-settings-cog", kids => {
|
||||
const contextMenuPatch: NavContextMenuPatchCallback = kids => {
|
||||
if (kids.some(k => k?.props?.id === NAV_ID)) return;
|
||||
|
||||
kids.unshift(
|
||||
|
@ -242,11 +234,22 @@ export default definePlugin({
|
|||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
export default definePlugin({
|
||||
name: "DevCompanion",
|
||||
description: "Dev Companion Plugin",
|
||||
authors: [Devs.Ven],
|
||||
dependencies: ["ContextMenuAPI"],
|
||||
|
||||
start() {
|
||||
initWs();
|
||||
addContextMenuPatch("user-settings-cog", contextMenuPatch);
|
||||
},
|
||||
|
||||
stop() {
|
||||
socket?.close(1000, "Plugin Stopped");
|
||||
socket = void 0;
|
||||
removeContextMenuPatch("user-settings-cog", contextMenuPatch);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -176,9 +176,9 @@ function CloneModal({ id, name: emojiName, isAnimated }: { id: string; name: str
|
|||
);
|
||||
}
|
||||
|
||||
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, args) => {
|
||||
if (!args?.[0]) return;
|
||||
const { favoriteableId, emoteClonerDataAlt, itemHref, itemSrc, favoriteableType } = args[0];
|
||||
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => {
|
||||
if (!props) return;
|
||||
const { favoriteableId, emoteClonerDataAlt, itemHref, itemSrc, favoriteableType } = props;
|
||||
|
||||
if (!emoteClonerDataAlt || favoriteableType !== "emoji") return;
|
||||
|
||||
|
|
|
@ -131,8 +131,8 @@ export default definePlugin({
|
|||
{
|
||||
find: ".activeCommandOption",
|
||||
replacement: {
|
||||
match: /(.)\.push.{1,50}\(\i,\{.{1,30}\},"gift"\)\)/,
|
||||
replace: "$&;try{$1.push($self.chatBarIcon())}catch{}",
|
||||
match: /(.)\.push.{1,30}disabled:(\i),.{1,20}\},"gift"\)\)/,
|
||||
replace: "$&;try{$2||$1.push($self.chatBarIcon())}catch{}",
|
||||
}
|
||||
},
|
||||
],
|
||||
|
|
|
@ -20,13 +20,15 @@ import { addClickListener, removeClickListener } from "@api/MessageEvents";
|
|||
import { migratePluginSettings } from "@api/settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findByPropsLazy, findLazy } from "@webpack";
|
||||
import { UserStore } from "@webpack/common";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { PermissionStore, UserStore } from "@webpack/common";
|
||||
|
||||
let isDeletePressed = false;
|
||||
const keydown = (e: KeyboardEvent) => e.key === "Backspace" && (isDeletePressed = true);
|
||||
const keyup = (e: KeyboardEvent) => e.key === "Backspace" && (isDeletePressed = false);
|
||||
|
||||
const MANAGE_CHANNELS = 1n << 4n;
|
||||
|
||||
migratePluginSettings("MessageClickActions", "MessageQuickActions");
|
||||
|
||||
export default definePlugin({
|
||||
|
@ -50,8 +52,6 @@ export default definePlugin({
|
|||
|
||||
start() {
|
||||
const MessageActions = findByPropsLazy("deleteMessage", "startEditMessage");
|
||||
const PermissionStore = findByPropsLazy("can", "initialize");
|
||||
const Permissions = findLazy(m => typeof m.MANAGE_MESSAGES === "bigint");
|
||||
const EditStore = findByPropsLazy("isEditing", "isEditingAny");
|
||||
|
||||
document.addEventListener("keydown", keydown);
|
||||
|
@ -64,7 +64,7 @@ export default definePlugin({
|
|||
MessageActions.startEditMessage(chan.id, msg.id, msg.content);
|
||||
event.preventDefault();
|
||||
}
|
||||
} else if (Vencord.Settings.plugins.MessageClickActions.enableDeleteOnClick && (isMe || PermissionStore.can(Permissions.MANAGE_MESSAGES, chan))) {
|
||||
} else if (Vencord.Settings.plugins.MessageClickActions.enableDeleteOnClick && (isMe || PermissionStore.can(MANAGE_CHANNELS, chan))) {
|
||||
MessageActions.deleteMessage(chan.id, msg.id);
|
||||
event.preventDefault();
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ function search(src: string, engine: string) {
|
|||
open(engine + encodeURIComponent(src), "_blank");
|
||||
}
|
||||
|
||||
const imageContextMenuPatch: NavContextMenuPatchCallback = (children, args) => {
|
||||
if (!args?.[0]) return;
|
||||
const { reverseImageSearchType, itemHref, itemSrc } = args[0];
|
||||
const imageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => {
|
||||
if (!props) return;
|
||||
const { reverseImageSearchType, itemHref, itemSrc } = props;
|
||||
|
||||
if (!reverseImageSearchType || reverseImageSearchType !== "img") return;
|
||||
|
||||
|
|
|
@ -321,9 +321,7 @@ export default definePlugin({
|
|||
],
|
||||
},
|
||||
{
|
||||
// The module wasn't being found, so lets just escape everything
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
find: "\^https\:\/\/\(\?\:canary\.\|ptb\.\)\?discord.com\/channels\/\(\\\\\d\+\|",
|
||||
find: "\"^/guild-stages/(\\\\d+)(?:/)?(\\\\d+)?\"",
|
||||
replacement: {
|
||||
// Make mentions of hidden channels work
|
||||
match: /\i\.\i\.can\(\i\.\i\.VIEW_CHANNEL,\i\)/,
|
||||
|
|
|
@ -40,6 +40,7 @@ function SilentMessageToggle() {
|
|||
return (
|
||||
<Tooltip text="Toggle Silent Message">
|
||||
{tooltipProps => (
|
||||
<div style={{ display: "flex" }}>
|
||||
<Button
|
||||
{...tooltipProps}
|
||||
onClick={() => setEnabled(prev => !prev)}
|
||||
|
@ -62,6 +63,7 @@ function SilentMessageToggle() {
|
|||
</svg>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</Tooltip>
|
||||
);
|
||||
|
@ -75,8 +77,8 @@ export default definePlugin({
|
|||
{
|
||||
find: ".activeCommandOption",
|
||||
replacement: {
|
||||
match: /"gift"\)\);(?<=(\i)\.push.+?)/,
|
||||
replace: (m, array) => `${m}${array}.push($self.SilentMessageToggle());`
|
||||
match: /"gift"\)\);(?<=(\i)\.push.+?disabled:(\i),.+?)/,
|
||||
replace: (m, array, disabled) => `${m}${disabled}||${array}.push($self.SilentMessageToggle());`
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -82,8 +82,8 @@ export default definePlugin({
|
|||
find: ".activeCommandOption",
|
||||
predicate: () => settings.store.showIcon,
|
||||
replacement: {
|
||||
match: /(.)\.push.{1,50}\(\i,\{.{1,30}\},"gift"\)\)/,
|
||||
replace: "$&;try{$1.push($self.chatBarIcon())}catch{}",
|
||||
match: /(.)\.push.{1,30}disabled:(\i),.{1,20}\},"gift"\)\)/,
|
||||
replace: "$&;try{$2||$1.push($self.chatBarIcon())}catch{}",
|
||||
}
|
||||
},
|
||||
],
|
||||
|
|
|
@ -56,8 +56,8 @@ export default definePlugin({
|
|||
find: "AudioContextSettingsMigrated",
|
||||
replacement: [
|
||||
{
|
||||
match: /(?<=updateAsync\("audioContextSettings".{0,50})(?=return (\i)\.volume=(\i))/,
|
||||
replace: (_, volumeOptions, newVolume) => `if(${newVolume}>200)return ${volumeOptions}.volume=200;`
|
||||
match: /(?<=updateAsync\("audioContextSettings".{0,350}return \i\.volume=)\i(?=})/,
|
||||
replace: "$&>200?200:$&"
|
||||
},
|
||||
{
|
||||
match: /(?<=Object\.entries\(\i\.localMutes\).+?volume:).+?(?=,)/,
|
Loading…
Reference in a new issue