Plugin
VoiceChatUtilities
This plugin allows you to perform multiple actions on an entire channel (move, mute, disconnect, etc.) (originally by dutake)
1
/*2
* FiveCord — a Discord client mod3
* Copyright (c) 2025 FiveCord4
* SPDX-License-Identifier: GPL-3.0-or-later5
*/6
7
import { NavContextMenuPatchCallback } from "@api/ContextMenu";8
import { Devs } from "@utils/constants";9
import definePlugin from "@utils/types";10
import { findStoreLazy } from "@webpack";11
import { GuildChannelStore, Menu, React, RestAPI, UserStore } from "@webpack/common";12
import type { Channel } from "discord-types/general";13
14
const VoiceStateStore = findStoreLazy("VoiceStateStore");15
16
function sendPatch(channel: Channel, body: Record<string, any>, bypass = false) {17
const usersVoice = VoiceStateStore.getVoiceStatesForChannel(channel.id); class="ts-cmt">// Get voice states by channel id18
const myId = UserStore.getCurrentUser().id; class="ts-cmt">// Get my user id19
20
Object.keys(usersVoice).forEach((key, index) => {21
const userVoice = usersVoice[key];22
23
if (bypass || userVoice.userId !== myId) {24
setTimeout(() => {25
RestAPI.patch({26
url: `/guilds/${channel.guild_id}/members/${userVoice.userId}`,27
body: body28
});29
}, index * 500);30
}31
});32
}33
34
interface VoiceChannelContextProps {35
channel: Channel;36
}37
38
const VoiceChannelContext: NavContextMenuPatchCallback = (children, { channel }: VoiceChannelContextProps) => {39
// only for voice and stage channels40
if (!channel || (channel.type !== 2 && channel.type !== 13)) return;41
const userCount = Object.keys(VoiceStateStore.getVoiceStatesForChannel(channel.id)).length;42
if (userCount === 0) return;43
44
const guildChannels: { VOCAL: { channel: Channel, comparator: number; }[]; } = GuildChannelStore.getChannels(channel.guild_id);45
const voiceChannels = guildChannels.VOCAL.map(({ channel }) => channel).filter(({ id }) => id !== channel.id);46
47
children.splice(48
-1,49
0,50
<Menu.MenuItem51
label="Voice Tools"52
key="voice-tools"53
id="voice-tools"54
>55
<Menu.MenuItem56
key="voice-tools-disconnect-all"57
id="voice-tools-disconnect-all"58
label="Disconnect all"59
action={() => sendPatch(channel, {60
channel_id: null,61
})}62
/>63
64
<Menu.MenuItem65
key="voice-tools-mute-all"66
id="voice-tools-mute-all"67
label="Mute all"68
action={() => sendPatch(channel, {69
mute: true,70
})}71
/>72
73
<Menu.MenuItem74
key="voice-tools-unmute-all"75
id="voice-tools-unmute-all"76
label="Unmute all"77
action={() => sendPatch(channel, {78
mute: false,79
})}80
/>81
82
<Menu.MenuItem83
key="voice-tools-deafen-all"84
id="voice-tools-deafen-all"85
label="Deafen all"86
action={() => sendPatch(channel, {87
deaf: true,88
})}89
/>90
91
<Menu.MenuItem92
key="voice-tools-undeafen-all"93
id="voice-tools-undeafen-all"94
label="Undeafen all"95
action={() => sendPatch(channel, {96
deaf: false,97
})}98
/>99
100
<Menu.MenuItem101
label="Move all"102
key="voice-tools-move-all"103
id="voice-tools-move-all"104
>105
{voiceChannels.map(voiceChannel => {106
return (107
<Menu.MenuItem108
key={voiceChannel.id}109
id={voiceChannel.id}110
label={voiceChannel.name}111
action={() => sendPatch(channel, {112
channel_id: voiceChannel.id,113
}, true)}114
/>115
);116
})}117
118
</Menu.MenuItem>119
</Menu.MenuItem>120
);121
};122
123
124
125
export default definePlugin({126
name: "VoiceChatUtilities",127
description: "This plugin allows you to perform multiple actions on an entire channel (move, mute, disconnect, etc.) (originally by dutake)",128
authors: [Devs.FiveCord],129
contextMenus: {130
"channel-context": VoiceChannelContext131
},132
});133