Make Messageclickactions Great Again! (#695)
forgive me father for i have sinned, and thank you prism for fixing my awful code
This commit is contained in:
parent
b13b351dfb
commit
bfc9ecb5e7
1 changed files with 32 additions and 54 deletions
|
|
@ -11,9 +11,9 @@ import { Devs, EquicordDevs } from "@utils/constants";
|
|||
import { copyWithToast, insertTextIntoChatInputBox } from "@utils/discord";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import type { Message } from "@vencord/discord-types";
|
||||
import type { Channel, Message } from "@vencord/discord-types";
|
||||
import { ApplicationIntegrationType, MessageFlags } from "@vencord/discord-types/enums";
|
||||
import { AuthenticationStore, Constants, EditMessageStore, FluxDispatcher, MessageActions, MessageTypeSets, PermissionsBits, PermissionStore, PinActions, RestAPI, showToast, Toasts, WindowStore } from "@webpack/common";
|
||||
import { AuthenticationStore, Constants, EditMessageStore, FluxDispatcher, MessageActions, MessageTypeSets, PermissionsBits, PermissionStore, PinActions, RestAPI, Toasts, WindowStore } from "@webpack/common";
|
||||
|
||||
type Modifier = "NONE" | "SHIFT" | "CTRL" | "ALT" | "BACKSPACE" | "DELETE";
|
||||
type ClickAction = "NONE" | "DELETE" | "COPY_LINK" | "COPY_ID" | "COPY_CONTENT" | "COPY_USER_ID" | "EDIT" | "REPLY" | "REACT" | "OPEN_THREAD" | "OPEN_TAB" | "EDIT_REPLY" | "QUOTE" | "PIN";
|
||||
|
|
@ -201,11 +201,20 @@ function showWarning(message: string) {
|
|||
});
|
||||
}
|
||||
|
||||
function isMessageReplyable(msg: Message) {
|
||||
return MessageTypeSets.REPLYABLE.has(msg.type) && !msg.hasFlag(MessageFlags.EPHEMERAL);
|
||||
}
|
||||
const canSend = (channel: Channel) =>
|
||||
!channel.guild_id || PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel);
|
||||
|
||||
async function toggleReaction(channelId: string, messageId: string, emoji: string, channel: { id: string; guild_id?: string | null; }, msg: Message) {
|
||||
const canDelete = (msg: Message, channel: Channel) => {
|
||||
const myId = AuthenticationStore.getId();
|
||||
return msg.author.id === myId ||
|
||||
PermissionStore.can(PermissionsBits.MANAGE_MESSAGES, channel) ||
|
||||
msg.interactionMetadata?.authorizing_integration_owners?.[ApplicationIntegrationType.USER_INSTALL] === myId;
|
||||
};
|
||||
|
||||
const canReply = (msg: Message) =>
|
||||
MessageTypeSets.REPLYABLE.has(msg.type) && !msg.hasFlag(MessageFlags.EPHEMERAL);
|
||||
|
||||
async function toggleReaction(channelId: string, messageId: string, emoji: string, channel: Channel, msg: Message) {
|
||||
const trimmed = emoji.trim();
|
||||
if (!trimmed) return;
|
||||
|
||||
|
|
@ -241,37 +250,11 @@ async function toggleReaction(channelId: string, messageId: string, emoji: strin
|
|||
}
|
||||
}
|
||||
|
||||
async function copyMessageLink(msg: Message, channel: { id: string; guild_id?: string | null; }) {
|
||||
const guildId = channel.guild_id ?? "@me";
|
||||
const link = `https://discord.com/channels/${guildId}/${channel.id}/${msg.id}`;
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(link);
|
||||
showToast("Message link copied", Toasts.Type.SUCCESS);
|
||||
} catch (e) {
|
||||
new Logger("MessageClickActions").error("Failed to copy link:", e);
|
||||
}
|
||||
function copyLink(msg: Message, channel: Channel) {
|
||||
copyWithToast(`https://discord.com/channels/${channel.guild_id ?? "@me"}/${channel.id}/${msg.id}`, "Link copied!");
|
||||
}
|
||||
|
||||
async function copyMessageId(msg: Message) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(msg.id);
|
||||
showToast("Message ID copied", Toasts.Type.SUCCESS);
|
||||
} catch (e) {
|
||||
new Logger("MessageClickActions").error("Failed to copy message ID:", e);
|
||||
}
|
||||
}
|
||||
|
||||
async function copyUserId(msg: Message) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(msg.author.id);
|
||||
showToast("User ID copied", Toasts.Type.SUCCESS);
|
||||
} catch (e) {
|
||||
new Logger("MessageClickActions").error("Failed to copy user ID:", e);
|
||||
}
|
||||
}
|
||||
|
||||
function togglePin(channel: { id: string; }, msg: Message) {
|
||||
function togglePin(channel: Channel, msg: Message) {
|
||||
if (!PermissionStore.can(PermissionsBits.MANAGE_MESSAGES, channel)) {
|
||||
showWarning("Cannot pin: Missing permissions");
|
||||
return;
|
||||
|
|
@ -284,8 +267,8 @@ function togglePin(channel: { id: string; }, msg: Message) {
|
|||
}
|
||||
}
|
||||
|
||||
function quoteMessage(channel: { id: string; guild_id?: string | null; isPrivate?: () => boolean; }, msg: Message) {
|
||||
if (!isMessageReplyable(msg)) {
|
||||
function quoteMessage(channel: Channel, msg: Message) {
|
||||
if (!canReply(msg)) {
|
||||
showWarning("Cannot quote this message type");
|
||||
return;
|
||||
}
|
||||
|
|
@ -314,13 +297,13 @@ function quoteMessage(channel: { id: string; guild_id?: string | null; isPrivate
|
|||
}
|
||||
}
|
||||
|
||||
function openInNewTab(msg: Message, channel: { id: string; guild_id?: string | null; }) {
|
||||
function openInNewTab(msg: Message, channel: Channel) {
|
||||
const guildId = channel.guild_id ?? "@me";
|
||||
const link = `https://discord.com/channels/${guildId}/${channel.id}/${msg.id}`;
|
||||
VencordNative.native.openExternal(link);
|
||||
}
|
||||
|
||||
function openInThread(msg: Message, channel: { id: string; }) {
|
||||
function openInThread(msg: Message, channel: Channel) {
|
||||
FluxDispatcher.dispatch({
|
||||
type: "OPEN_THREAD_FLOW_MODAL",
|
||||
channelId: channel.id,
|
||||
|
|
@ -331,16 +314,15 @@ function openInThread(msg: Message, channel: { id: string; }) {
|
|||
async function executeAction(
|
||||
action: ClickAction,
|
||||
msg: Message,
|
||||
channel: { id: string; guild_id?: string | null; isDM?: () => boolean; isSystemDM?: () => boolean; isPrivate?: () => boolean; },
|
||||
channel: Channel,
|
||||
event: MouseEvent
|
||||
) {
|
||||
const myId = AuthenticationStore.getId();
|
||||
const isMe = msg.author.id === myId;
|
||||
const isSelfInvokedUserApp = msg.interactionMetadata?.authorizing_integration_owners?.[ApplicationIntegrationType.USER_INSTALL] === myId;
|
||||
|
||||
switch (action) {
|
||||
case "DELETE":
|
||||
if (!(isMe || PermissionStore.can(PermissionsBits.MANAGE_MESSAGES, channel) || isSelfInvokedUserApp)) return;
|
||||
if (!canDelete(msg, channel)) return;
|
||||
|
||||
if (msg.deleted) {
|
||||
FluxDispatcher.dispatch({
|
||||
|
|
@ -356,12 +338,12 @@ async function executeAction(
|
|||
break;
|
||||
|
||||
case "COPY_LINK":
|
||||
await copyMessageLink(msg, channel);
|
||||
copyLink(msg, channel);
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
case "COPY_ID":
|
||||
await copyMessageId(msg);
|
||||
copyWithToast(msg.id, "Message ID copied!");
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
|
|
@ -371,7 +353,7 @@ async function executeAction(
|
|||
break;
|
||||
|
||||
case "COPY_USER_ID":
|
||||
await copyUserId(msg);
|
||||
copyWithToast(msg.author.id, "User ID copied!");
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
|
|
@ -383,8 +365,8 @@ async function executeAction(
|
|||
break;
|
||||
|
||||
case "REPLY":
|
||||
if (!MessageTypeSets.REPLYABLE.has(msg.type) || msg.hasFlag(MessageFlags.EPHEMERAL)) return;
|
||||
if (channel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return;
|
||||
if (!canReply(msg)) return;
|
||||
if (!canSend(channel)) return;
|
||||
|
||||
const isShiftPress = event.shiftKey;
|
||||
const shouldMention = isPluginEnabled(NoReplyMentionPlugin.name)
|
||||
|
|
@ -406,8 +388,8 @@ async function executeAction(
|
|||
if (EditMessageStore.isEditing(channel.id, msg.id) || msg.state !== "SENT") return;
|
||||
MessageActions.startEditMessage(channel.id, msg.id, msg.content);
|
||||
} else {
|
||||
if (!MessageTypeSets.REPLYABLE.has(msg.type) || msg.hasFlag(MessageFlags.EPHEMERAL)) return;
|
||||
if (channel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return;
|
||||
if (!canReply(msg)) return;
|
||||
if (!canSend(channel)) return;
|
||||
|
||||
const shouldMentionReply = isPluginEnabled(NoReplyMentionPlugin.name)
|
||||
? NoReplyMentionPlugin.shouldMention(msg, false)
|
||||
|
|
@ -490,10 +472,6 @@ export default definePlugin({
|
|||
let target = event.target as HTMLElement;
|
||||
if (target.nodeType === Node.TEXT_NODE) target = target.parentElement as HTMLElement;
|
||||
|
||||
// dont look, please just dont
|
||||
if (target.closest('a, button, input, img, video, audio, [role="button"], [role="link"], [role="menuitem"], [class*="repliedTextPreview"], [class*="threadMessageAccessory"], [class*="spoilerText"], [class*="mention"]')) return;
|
||||
if (!target.closest('[class*="message"]')) return;
|
||||
|
||||
const myId = AuthenticationStore.getId();
|
||||
const isMe = msg.author.id === myId;
|
||||
const isDM = channel.isDM();
|
||||
|
|
@ -545,7 +523,7 @@ export default definePlugin({
|
|||
}
|
||||
|
||||
const executeDoubleClick = () => {
|
||||
if (channel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return;
|
||||
if (!canSend(channel)) return;
|
||||
if (msg.deleted === true) return;
|
||||
if (canDoubleClick) {
|
||||
executeAction(doubleClickAction, msg, channel, event);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue