Plugin

MessageClickActions

Hold Backspace and click to delete, double click to edit/reply

Chat Shortcuts
index.ts
Download

Source

src/plugins/messageClickActions/index.ts
1import { isPluginEnabled } from "@api/PluginManager";
2import { definePluginSettings } from "@api/Settings";
3import NoReplyMentionPlugin from "@plugins/noReplyMention";
4import { Devs } from "@utils/constants";
5import definePlugin, { OptionType } from "@utils/types";
6import { ApplicationIntegrationType, MessageFlags } from "@vencord/discord-types/enums";
7import { findByPropsLazy } from "@webpack";
8import { AuthenticationStore, FluxDispatcher, MessageTypeSets, PermissionsBits, PermissionStore, WindowStore } from "@webpack/common";
9
10const MessageActions = findByPropsLazy("deleteMessage", "startEditMessage");
11const EditStore = findByPropsLazy("isEditing", "isEditingAny");
12
13let isDeletePressed = false;
14const keydown = (e: KeyboardEvent) => e.key === "Backspace" && (isDeletePressed = true);
15const keyup = (e: KeyboardEvent) => e.key === "Backspace" && (isDeletePressed = false);
16const focusChanged = () => !WindowStore.isFocused() && (isDeletePressed = false);
17
18const settings = definePluginSettings({
19 enableDeleteOnClick: {
20 type: OptionType.BOOLEAN,
21 description: "Enable delete on click while holding backspace",
22 default: true
23 },
24 enableDoubleClickToEdit: {
25 type: OptionType.BOOLEAN,
26 description: "Enable double click to edit",
27 default: true
28 },
29 enableDoubleClickToReply: {
30 type: OptionType.BOOLEAN,
31 description: "Enable double click to reply",
32 default: true
33 },
34 requireModifier: {
35 type: OptionType.BOOLEAN,
36 description: "Only do double click actions when shift/ctrl is held",
37 default: false
38 }
39});
40
41export default definePlugin({
42 name: "MessageClickActions",
43 description: "Hold Backspace and click to delete, double click to edit/reply",
44 tags: ["Chat", "Shortcuts"],
45 authors: [Devs.Ven],
46
47 settings,
48
49 start() {
50 document.addEventListener("keydown", keydown);
51 document.addEventListener("keyup", keyup);
52 WindowStore.addChangeListener(focusChanged);
53 },
54
55 stop() {
56 document.removeEventListener("keydown", keydown);
57 document.removeEventListener("keyup", keyup);
58 WindowStore.removeChangeListener(focusChanged);
59 },
60
61 onMessageClick(msg, channel, event) {
62 const myId = AuthenticationStore.getId();
63 const isMe = msg.author.id === myId;
64 const isSelfInvokedUserApp = msg.interactionMetadata?.authorizing_integration_owners[ApplicationIntegrationType.USER_INSTALL] === myId;
65 if (!isDeletePressed) {
66 if (event.detail < 2) return;
67 if (settings.store.requireModifier && !event.ctrlKey && !event.shiftKey) return;
68 if (channel.guild_id && !PermissionStore.can(PermissionsBits.SEND_MESSAGES, channel)) return;
69 if (msg.deleted === true) return;
70
71 if (isMe) {
72 if (!settings.store.enableDoubleClickToEdit || EditStore.isEditing(channel.id, msg.id) || msg.state !== "SENT") return;
73
74 MessageActions.startEditMessage(channel.id, msg.id, msg.content);
75 event.preventDefault();
76 } else {
77 if (!settings.store.enableDoubleClickToReply) return;
78
79 if (!MessageTypeSets.REPLYABLE.has(msg.type) || msg.hasFlag(MessageFlags.EPHEMERAL)) return;
80
81 const isShiftPress = event.shiftKey && !settings.store.requireModifier;
82 const shouldMention = isPluginEnabled(NoReplyMentionPlugin.name)
83 ? NoReplyMentionPlugin.shouldMention(msg, isShiftPress)
84 : !isShiftPress;
85
86 FluxDispatcher.dispatch({
87 type: "CREATE_PENDING_REPLY",
88 channel,
89 message: msg,
90 shouldMention,
91 showMentionToggle: channel.guild_id !== null
92 });
93 }
94 } else if (settings.store.enableDeleteOnClick && (isMe || PermissionStore.can(PermissionsBits.MANAGE_MESSAGES, channel) || isSelfInvokedUserApp)) {
95 if (msg.deleted) {
96 FluxDispatcher.dispatch({
97 type: "MESSAGE_DELETE",
98 channelId: channel.id,
99 id: msg.id,
100 mlDeleted: true
101 });
102 } else {
103 MessageActions.deleteMessage(channel.id, msg.id);
104 }
105 event.preventDefault();
106 }
107 },
108});
109