From 76d9f76faee85f91f6b1cb106571d268e4e252dc Mon Sep 17 00:00:00 2001 From: Key Date: Wed, 21 Jan 2026 12:44:18 +0000 Subject: [PATCH] fix(MessageClickActions): single clicks no longer trigger double click actions (#667) * fix(MessageClickActions): single clicks no longer trigger double click actions a somewhat hacky fix but it works * feat(MessageClickActions): add DELETE modifier key --- src/plugins/messageClickActions/index.ts | 82 ++++++++++++++++-------- 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/src/plugins/messageClickActions/index.ts b/src/plugins/messageClickActions/index.ts index 6f52d1aae..4ba26936a 100644 --- a/src/plugins/messageClickActions/index.ts +++ b/src/plugins/messageClickActions/index.ts @@ -15,7 +15,7 @@ import type { 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"; -type Modifier = "NONE" | "SHIFT" | "CTRL" | "ALT" | "BACKSPACE"; +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"; const actions: { label: string; value: ClickAction; }[] = [ @@ -65,6 +65,7 @@ const modifiers: { label: string; value: Modifier; }[] = [ const singleClickModifiers: { label: string; value: Modifier; }[] = [ { label: "Backspace", value: "BACKSPACE" }, + { label: "Delete", value: "DELETE" }, ...modifiers ]; @@ -73,11 +74,13 @@ const keydown = (e: KeyboardEvent) => { const mod = modifierFromKey(e); if (mod) pressedModifiers.add(mod); if (e.key === "Backspace") pressedModifiers.add("BACKSPACE"); + if (e.key === "Delete") pressedModifiers.add("DELETE"); }; const keyup = (e: KeyboardEvent) => { const mod = modifierFromKey(e); if (mod) pressedModifiers.delete(mod); if (e.key === "Backspace") pressedModifiers.delete("BACKSPACE"); + if (e.key === "Delete") pressedModifiers.delete("DELETE"); }; const focusChanged = () => { if (!WindowStore.isFocused()) { @@ -97,6 +100,7 @@ function isModifierPressed(modifier: Modifier): boolean { } let doubleClickTimeout: ReturnType | null = null; +let singleClickTimeout: ReturnType | null = null; let pendingDoubleClickAction: (() => void) | null = null; const settings = definePluginSettings({ @@ -461,6 +465,10 @@ export default definePlugin({ clearTimeout(doubleClickTimeout); doubleClickTimeout = null; } + if (singleClickTimeout) { + clearTimeout(singleClickTimeout); + singleClickTimeout = null; + } pendingDoubleClickAction = null; }, @@ -486,6 +494,11 @@ export default definePlugin({ const isDoubleClick = event.detail === 2; const isTripleClick = event.detail === 3; + if (singleClickTimeout) { + clearTimeout(singleClickTimeout); + singleClickTimeout = null; + } + if (isTripleClick) { if (doubleClickTimeout) { clearTimeout(doubleClickTimeout); @@ -499,37 +512,50 @@ export default definePlugin({ return; } - if (!isDoubleClick) { - if (isSingleClick && isModifierPressed(singleClickModifier) && singleClickAction !== "NONE") { - executeAction(singleClickAction, msg, channel, event); - return; - } - } - - const executeDoubleClick = () => { - if (channel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return; - if (msg.deleted === true) return; - if (doubleClickAction !== "NONE") { - executeAction(doubleClickAction, msg, channel, event); - } - }; - + const canDoubleClick = (isModifierPressed(doubleClickModifier) || doubleClickModifier === "NONE") && doubleClickAction !== "NONE"; const canTripleClick = isModifierPressed(tripleClickModifier) && tripleClickAction !== "NONE"; - if (canTripleClick) { - if (doubleClickTimeout) { - clearTimeout(doubleClickTimeout); + if (isDoubleClick) { + const executeDoubleClick = () => { + if (channel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return; + if (msg.deleted === true) return; + if (canDoubleClick) { + executeAction(doubleClickAction, msg, channel, event); + } + }; + + if (canTripleClick) { + if (doubleClickTimeout) { + clearTimeout(doubleClickTimeout); + } + pendingDoubleClickAction = executeDoubleClick; + doubleClickTimeout = setTimeout(() => { + pendingDoubleClickAction?.(); + pendingDoubleClickAction = null; + doubleClickTimeout = null; + }, settings.store.clickTimeout); + } else { + executeDoubleClick(); } - pendingDoubleClickAction = executeDoubleClick; - doubleClickTimeout = setTimeout(() => { - pendingDoubleClickAction?.(); - pendingDoubleClickAction = null; - doubleClickTimeout = null; - }, settings.store.clickTimeout); - event.preventDefault(); - } else if (isDoubleClick && (isModifierPressed(doubleClickModifier) || doubleClickModifier === "NONE")) { - executeDoubleClick(); event.preventDefault(); + return; + } + + if (isSingleClick) { + const executeSingleClick = () => { + if (isModifierPressed(singleClickModifier) && singleClickAction !== "NONE") { + executeAction(singleClickAction, msg, channel, event); + } + }; + + if (canDoubleClick) { + singleClickTimeout = setTimeout(() => { + executeSingleClick(); + singleClickTimeout = null; + }, settings.store.clickTimeout); + } else { + executeSingleClick(); + } } }, });