Plugin

VoiceChatUtilities

This plugin allows you to perform multiple actions on an entire channel (move, mute, disconnect, etc.) (originally by dutake)

index.tsx
Download

Source

src/plugins/voiceChatUtils/index.tsx
1/*
2 * FiveCord — a Discord client mod
3 * Copyright (c) 2025 FiveCord
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 */
6
7import { NavContextMenuPatchCallback } from "@api/ContextMenu";
8import { Devs } from "@utils/constants";
9import definePlugin from "@utils/types";
10import { findStoreLazy } from "@webpack";
11import { GuildChannelStore, Menu, React, RestAPI, UserStore } from "@webpack/common";
12import type { Channel } from "discord-types/general";
13
14const VoiceStateStore = findStoreLazy("VoiceStateStore");
15
16function sendPatch(channel: Channel, body: Record<string, any>, bypass = false) {
17 const usersVoice = VoiceStateStore.getVoiceStatesForChannel(channel.id); class="ts-cmt">// Get voice states by channel id
18 const myId = UserStore.getCurrentUser().id; class="ts-cmt">// Get my user id
19
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: body
28 });
29 }, index * 500);
30 }
31 });
32}
33
34interface VoiceChannelContextProps {
35 channel: Channel;
36}
37
38const VoiceChannelContext: NavContextMenuPatchCallback = (children, { channel }: VoiceChannelContextProps) => {
39 // only for voice and stage channels
40 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.MenuItem
51 label="Voice Tools"
52 key="voice-tools"
53 id="voice-tools"
54 >
55 <Menu.MenuItem
56 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.MenuItem
65 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.MenuItem
74 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.MenuItem
83 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.MenuItem
92 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.MenuItem
101 label="Move all"
102 key="voice-tools-move-all"
103 id="voice-tools-move-all"
104 >
105 {voiceChannels.map(voiceChannel => {
106 return (
107 <Menu.MenuItem
108 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
125export 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": VoiceChannelContext
131 },
132});
133