diff --git a/packages/discord-types/src/components.d.ts b/packages/discord-types/src/components.d.ts index 8d0aa0ed4..88884b8d6 100644 --- a/packages/discord-types/src/components.d.ts +++ b/packages/discord-types/src/components.d.ts @@ -331,6 +331,15 @@ declare enum PopoutAnimation { type PopoutPosition = "top" | "bottom" | "left" | "right" | "center" | "window_center"; +export interface PopoutProps { + position: PopoutPosition; + nudge: number; + isPositioned: boolean; + setPopoutRef(ref: any): void; + closePopout(): void; + updatePosition(): void; +} + export type Popout = ComponentType<{ children( thing: { @@ -347,14 +356,8 @@ export type Popout = ComponentType<{ ): ReactNode; shouldShow?: boolean; targetElementRef: RefObject; - renderPopout(args: { - closePopout(): void; - isPositioned: boolean; - nudge: number; - position: PopoutPosition; - setPopoutRef(ref: any): void; - updatePosition(): void; - }): ReactNode; + renderPopout(props: PopoutProps): ReactNode; + preload?(): Promise; onRequestOpen?(): void; onRequestClose?(): void; diff --git a/src/plugins/betterRoleContext/index.tsx b/src/plugins/betterRoleContext/index.tsx index 61343418e..e31c7613a 100644 --- a/src/plugins/betterRoleContext/index.tsx +++ b/src/plugins/betterRoleContext/index.tsx @@ -9,12 +9,17 @@ import { getUserSettingLazy } from "@api/UserSettings"; import { ImageIcon } from "@components/Icons"; import { copyToClipboard } from "@utils/clipboard"; import { Devs } from "@utils/constants"; -import { getCurrentGuild, openImageModal } from "@utils/discord"; +import { getCurrentChannel, getCurrentGuild, openImageModal } from "@utils/discord"; +import { classes } from "@utils/misc"; import definePlugin, { OptionType } from "@utils/types"; -import { findByPropsLazy } from "@webpack"; -import { GuildRoleStore, Menu, PermissionStore } from "@webpack/common"; +import { PopoutProps } from "@vencord/discord-types"; +import { findByCodeLazy, findByPropsLazy, findCssClassesLazy } from "@webpack"; +import { GuildRoleStore, Menu, PermissionStore, Popout, useRef } from "@webpack/common"; +import { ComponentType } from "react"; const GuildSettingsActions = findByPropsLazy("open", "selectRole", "updateGuild"); +const MenuItemClasses = findCssClassesLazy("item", "labelContainer", "colorDefault", "label", "iconContainer"); +const loadRoleMembers = findByCodeLazy(".GUILD_ROLE_MEMBER_IDS(", "requestMembersById"); const DeveloperMode = getUserSettingLazy("appearance", "developerMode")!; @@ -40,6 +45,14 @@ function AppearanceIcon() { ); } +function RoleMembersIcon() { + return ( + + + + ); +} + const settings = definePluginSettings({ roleIconFileFormat: { type: OptionType.SELECT, @@ -62,6 +75,16 @@ const settings = definePluginSettings({ } }); +interface RoleMemberPopoutProps { + popoutProps: PopoutProps; + guildId: string; + channelId: string; + roleId: string; +} +type RoleMemberPopout = ComponentType; + +let RoleMemberPopout: RoleMemberPopout = () => null; + export default definePlugin({ name: "BetterRoleContext", description: "Adds options to copy role color / edit role / view role icon when right clicking roles in the user profile", @@ -71,13 +94,27 @@ export default definePlugin({ settings, + patches: [{ + find: ".ROLE_MENTION)", + replacement: { + match: /function (\i)(?=.+?renderPopout:.{0,20}\1,\{guildId:\i,channelId:\i)/, + replace: "$self.RoleMembers=$1;$&" + } + }], + start() { // DeveloperMode needs to be enabled for the context menu to be shown DeveloperMode.updateSetting(true); }, + set RoleMembers(component: RoleMemberPopout) { + RoleMemberPopout = component; + }, + contextMenus: { "dev-context"(children, { id }: { id: string; }) { + const popoutRef = useRef(null); + const guild = getCurrentGuild(); if (!guild) return; @@ -126,6 +163,39 @@ export default definePlugin({ ); } + + children.push( + ( + loadRoleMembers(guild.id, id)} + renderPopout={popoutProps => ( + + )} + > + {popoutProps => ( +
+
View Role Members
+
+ +
+
+ )} +
+ )} /> + ); } } });