feat(plugin): User Voice Show (#694)
Co-authored-by: V <vendicated@riseup.net> Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									df7357b357
								
							
						
					
					
						commit
						e261c93563
					
				
					 4 changed files with 188 additions and 0 deletions
				
			
		
							
								
								
									
										18
									
								
								src/plugins/userVoiceShow/components/VoiceChannelSection.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/plugins/userVoiceShow/components/VoiceChannelSection.css
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| .vc-uvs-button > div { | ||||
|     white-space: normal !important; | ||||
| } | ||||
| 
 | ||||
| .vc-uvs-button { | ||||
|     width: 100%; | ||||
|     margin: auto; | ||||
|     height: unset; | ||||
| } | ||||
| 
 | ||||
| .vc-uvs-header { | ||||
|     color: var(--header-primary); | ||||
|     margin-bottom: 6px; | ||||
| } | ||||
| 
 | ||||
| .vc-uvs-modal-margin > [class^="section"] { | ||||
|     margin: 0 12px; | ||||
| } | ||||
							
								
								
									
										61
									
								
								src/plugins/userVoiceShow/components/VoiceChannelSection.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/plugins/userVoiceShow/components/VoiceChannelSection.tsx
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,61 @@ | |||
| /* | ||||
|  * Vencord, a modification for Discord's desktop app | ||||
|  * Copyright (c) 2023 Vendicated and contributors | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| 
 | ||||
| import "./VoiceChannelSection.css"; | ||||
| 
 | ||||
| import { findByCodeLazy, findByPropsLazy } from "@webpack"; | ||||
| import { Button, Forms, PermissionStore, Toasts } from "@webpack/common"; | ||||
| import { Channel } from "discord-types/general"; | ||||
| 
 | ||||
| const ChannelActions = findByPropsLazy("selectChannel", "selectVoiceChannel"); | ||||
| const UserPopoutSection = findByCodeLazy(".lastSection", ".children"); | ||||
| 
 | ||||
| const CONNECT = 1n << 20n; | ||||
| 
 | ||||
| interface VoiceChannelFieldProps { | ||||
|     channel: Channel; | ||||
|     label: string; | ||||
|     showHeader: boolean; | ||||
| } | ||||
| 
 | ||||
| export const VoiceChannelSection = ({ channel, label, showHeader }: VoiceChannelFieldProps) => ( | ||||
|     <UserPopoutSection> | ||||
|         {showHeader && <Forms.FormTitle className="vc-uvs-header">In a voice channel</Forms.FormTitle>} | ||||
|         <Button | ||||
|             className="vc-uvs-button" | ||||
|             color={Button.Colors.TRANSPARENT} | ||||
|             size={Button.Sizes.SMALL} | ||||
| 
 | ||||
|             onClick={() => { | ||||
|                 if (PermissionStore.can(CONNECT, channel)) | ||||
|                     ChannelActions.selectVoiceChannel(channel.id); | ||||
|                 else | ||||
|                     Toasts.show({ | ||||
|                         message: "Insufficient permissions to enter the channel.", | ||||
|                         id: "user-voice-show-insufficient-permissions", | ||||
|                         type: Toasts.Type.FAILURE, | ||||
|                         options: { | ||||
|                             position: Toasts.Position.BOTTOM, | ||||
|                         } | ||||
|                     }); | ||||
|             }} | ||||
|         > | ||||
|             {label} | ||||
|         </Button> | ||||
|     </UserPopoutSection> | ||||
| ); | ||||
							
								
								
									
										105
									
								
								src/plugins/userVoiceShow/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/plugins/userVoiceShow/index.tsx
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,105 @@ | |||
| /* | ||||
|  * Vencord, a modification for Discord's desktop app | ||||
|  * Copyright (c) 2023 Vendicated and contributors | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| 
 | ||||
| import { definePluginSettings } from "@api/settings"; | ||||
| import ErrorBoundary from "@components/ErrorBoundary"; | ||||
| import { Devs } from "@utils/constants"; | ||||
| import definePlugin, { OptionType } from "@utils/types"; | ||||
| import { findStoreLazy } from "@webpack"; | ||||
| import { ChannelStore, GuildStore } from "@webpack/common"; | ||||
| import { User } from "discord-types/general"; | ||||
| 
 | ||||
| import { VoiceChannelSection } from "./components/VoiceChannelSection"; | ||||
| 
 | ||||
| const VoiceStateStore = findStoreLazy("VoiceStateStore"); | ||||
| 
 | ||||
| const settings = definePluginSettings({ | ||||
|     showInUserProfileModal: { | ||||
|         type: OptionType.BOOLEAN, | ||||
|         description: "Show a user's voice channel in their profile modal", | ||||
|         default: true, | ||||
|     }, | ||||
|     showVoiceChannelSectionHeader: { | ||||
|         type: OptionType.BOOLEAN, | ||||
|         description: 'Whether to show "IN A VOICE CHANNEL" above the join button', | ||||
|         default: true, | ||||
|     } | ||||
| }); | ||||
| 
 | ||||
| interface UserProps { | ||||
|     user: User; | ||||
| } | ||||
| 
 | ||||
| const VoiceChannelField = ErrorBoundary.wrap(({ user }: UserProps) => { | ||||
|     const { channelId } = VoiceStateStore.getVoiceStateForUser(user.id) ?? {}; | ||||
|     if (!channelId) return null; | ||||
| 
 | ||||
|     const channel = ChannelStore.getChannel(channelId); | ||||
|     const guild = GuildStore.getGuild(channel.guild_id); | ||||
| 
 | ||||
|     if (!guild) return null; // When in DM call
 | ||||
| 
 | ||||
|     const result = `${guild.name} | ${channel.name}`; | ||||
| 
 | ||||
|     return ( | ||||
|         <VoiceChannelSection | ||||
|             channel={channel} | ||||
|             label={result} | ||||
|             showHeader={settings.store.showVoiceChannelSectionHeader} | ||||
|         /> | ||||
|     ); | ||||
| }); | ||||
| 
 | ||||
| export default definePlugin({ | ||||
|     name: "UserVoiceShow", | ||||
|     description: "Shows whether a User is currently in a voice channel somewhere in their profile", | ||||
|     authors: [Devs.LordElias], | ||||
|     settings, | ||||
| 
 | ||||
|     patchModal({ user }: UserProps) { | ||||
|         if (!settings.store.showInUserProfileModal) | ||||
|             return null; | ||||
| 
 | ||||
|         return ( | ||||
|             <div className="vc-uvs-modal-margin"> | ||||
|                 <VoiceChannelField user={user} /> | ||||
|             </div> | ||||
|         ); | ||||
|     }, | ||||
| 
 | ||||
|     patchPopout: ({ user }: UserProps) => <VoiceChannelField user={user} />, | ||||
| 
 | ||||
|     patches: [ | ||||
|         { | ||||
|             find: ".showCopiableUsername", | ||||
|             replacement: { | ||||
|                 match: /\(0,\w\.jsx\)\(\w{2},{user:\w,setNote/, | ||||
|                 // paste my fancy custom button above the message field
 | ||||
|                 replace: "$self.patchPopout(arguments[0]),$&", | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             find: ".USER_PROFILE_MODAL", | ||||
|             replacement: { | ||||
|                 match: /,{user:\w{1,2}}\)(?!;case)/, | ||||
|                 // paste my fancy custom button below the username
 | ||||
|                 replace: "$&,$self.patchModal(arguments[0])", | ||||
|             } | ||||
|         } | ||||
|     ], | ||||
| }); | ||||
|  | @ -226,6 +226,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({ | |||
|         name: "TheKodeToad", | ||||
|         id: 706152404072267788n | ||||
|     }, | ||||
|     LordElias: { | ||||
|         name: "LordElias", | ||||
|         id: 319460781567639554n | ||||
|     }, | ||||
|     juby: { | ||||
|         name: "Juby210", | ||||
|         id: 324622488644616195n | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue