Plugin
VoiceChatDoubleClick
Join voice chats via double click instead of single click
1
import { Devs } from "@utils/constants";2
import definePlugin from "@utils/types";3
import { ChannelStore, SelectedChannelStore } from "@webpack/common";4
5
const timers = {} as Record<string, {6
timeout?: NodeJS.Timeout;7
i: number;8
}>;9
10
export default definePlugin({11
name: "VoiceChatDoubleClick",12
description: "Join voice chats via double click instead of single click",13
tags: ["Voice"],14
authors: [Devs.Ven, Devs.D3SOX],15
patches: [16
// Stage Channels & Voice Channels17
// the find is for stage channels, but it also handles voice18
// channels because they're both in the same concatenated module19
// the find for voice channels was `.handleVoiceStatusClick`20
{21
find: ".handleClickChat",22
// hack: these are not React onClick, it is a custom prop handled by Discord23
// thus, replacing this with onDoubleClick won't work, and you also cannot check24
// e.detail since instead of the event they pass the channel.25
// do this timer workaround instead26
replacement: [27
{28
match: /onClick:\(\)=>\{this.handleClick\(\)/g,29
replace: "onClick:()=>{$self.schedule(()=>{this.handleClick()},this)",30
},31
]32
},33
{34
// channel mentions35
find: 039;className:"channelMention",children:[null!=039;,36
replacement: {37
match: /onClick:(\i)(?=,.{0,30}className:"channelMention".+?(\i)\.inContent)/,38
replace: (_, onClick, props) => ""39
+ `onClick:(vcDoubleClickEvt)=>$self.shouldRunOnClick(vcDoubleClickEvt,${props})&&${onClick}()`,40
}41
}42
],43
44
shouldRunOnClick(e: MouseEvent, { channelId }) {45
const channel = ChannelStore.getChannel(channelId);46
if (!channel || ![2, 13].includes(channel.type)) return true;47
return e.detail >= 2;48
},49
50
schedule(cb: () => void, e: any) {51
const id = e.props.channel.id as string;52
if (SelectedChannelStore.getVoiceChannelId() === id) {53
cb();54
return;55
}56
// use a different counter for each channel57
const data = (timers[id] ??= { timeout: void 0, i: 0 });58
// clear any existing timer59
clearTimeout(data.timeout);60
61
// if we already have 2 or more clicks, run the callback immediately62
if (++data.i >= 2) {63
cb();64
delete timers[id];65
} else {66
// else reset the counter in 500ms67
data.timeout = setTimeout(() => {68
delete timers[id];69
}, 500);70
}71
}72
});73