diff --git a/src/equicordplugins/followVoiceUser/index.tsx b/src/equicordplugins/followVoiceUser/index.tsx new file mode 100644 index 00000000..f88df7f3 --- /dev/null +++ b/src/equicordplugins/followVoiceUser/index.tsx @@ -0,0 +1,117 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2025 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { NavContextMenuPatchCallback } from "@api/ContextMenu"; +import { definePluginSettings } from "@api/Settings"; +import { EquicordDevs } from "@utils/constants"; +import definePlugin, { OptionType } from "@utils/types"; +import { findByPropsLazy, findStoreLazy } from "@webpack"; +import { Menu, React } from "@webpack/common"; +import { VoiceState } from "@webpack/types"; +import { Channel, User } from "discord-types/general"; + +type TFollowedUserInfo = { + lastChannelId: string; + userId: string; +} | null; + +interface UserContextProps { + channel: Channel; + user: User; + guildId?: string; +} + +let followedUserInfo: TFollowedUserInfo = null; + +const voiceChannelAction = findByPropsLazy("selectVoiceChannel"); +const VoiceStateStore = findStoreLazy("VoiceStateStore"); +const UserStore = findStoreLazy("UserStore"); +const RelationshipStore = findStoreLazy("RelationshipStore"); + +const settings = definePluginSettings({ + onlyWhenInVoice: { + type: OptionType.BOOLEAN, + default: true, + description: "Only follow the user when you are in a voice channel" + }, + leaveWhenUserLeaves: { + type: OptionType.BOOLEAN, + default: false, + description: "Leave the voice channel when the user leaves. (That can cause you to sometimes enter infinite leave/join loop)" + } +}); + +const UserContextMenuPatch: NavContextMenuPatchCallback = (children, { channel, user }: UserContextProps) => { + if (UserStore.getCurrentUser().id === user.id || !RelationshipStore.getFriendIDs().includes(user.id)) return; + + const [checked, setChecked] = React.useState(followedUserInfo?.userId === user.id); + + children.push( +