diff --git a/src/plugins/betterRoleContext/index.tsx b/src/plugins/betterRoleContext/index.tsx index e31c7613a..e8e6e7bf9 100644 --- a/src/plugins/betterRoleContext/index.tsx +++ b/src/plugins/betterRoleContext/index.tsx @@ -10,9 +10,10 @@ import { ImageIcon } from "@components/Icons"; import { copyToClipboard } from "@utils/clipboard"; import { Devs } from "@utils/constants"; import { getCurrentChannel, getCurrentGuild, openImageModal } from "@utils/discord"; +import { isTruthy } from "@utils/guards"; import { classes } from "@utils/misc"; import definePlugin, { OptionType } from "@utils/types"; -import { PopoutProps } from "@vencord/discord-types"; +import { Guild, PopoutProps, Role } from "@vencord/discord-types"; import { findByCodeLazy, findByPropsLazy, findCssClassesLazy } from "@webpack"; import { GuildRoleStore, Menu, PermissionStore, Popout, useRef } from "@webpack/common"; import { ComponentType } from "react"; @@ -85,6 +86,90 @@ type RoleMemberPopout = ComponentType; let RoleMemberPopout: RoleMemberPopout = () => null; +export function buildExtraRoleContextMenuItems(role: Role, guild: Guild, popoutRef?: React.RefObject) { + if (!role) return { before: [], after: [] }; + + const before = [ + PermissionStore.getGuildPermissionProps(guild).canManageRoles && ( + { + await GuildSettingsActions.open(guild.id, "ROLES"); + GuildSettingsActions.selectRole(role.id); + }} + icon={PencilIcon} + /> + ), + role.colorString && ( + copyToClipboard(role.colorString!)} + icon={AppearanceIcon} + /> + ) + ].filter(isTruthy); + + const after = [ + role.icon && ( + { + openImageModal({ + url: `${location.protocol}//${window.GLOBAL_ENV.CDN_HOST}/role-icons/${role.id}/${role.icon}.${settings.store.roleIconFileFormat}`, + height: 128, + width: 128 + }); + }} + icon={ImageIcon} + /> + ), + popoutRef && ( + ( + loadRoleMembers(guild.id, role.id)} + renderPopout={popoutProps => ( + + )} + > + {popoutProps => ( +
+
View Role Members
+
+ +
+
+ )} +
+ )} + /> + ) + ].filter(isTruthy); + + return { before, after }; +} + 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", @@ -121,81 +206,9 @@ export default definePlugin({ const role = GuildRoleStore.getRole(guild.id, id); if (!role) return; - if (role.colorString) { - children.unshift( - copyToClipboard(role.colorString!)} - icon={AppearanceIcon} - /> - ); - } - - if (PermissionStore.getGuildPermissionProps(guild).canManageRoles) { - children.unshift( - { - await GuildSettingsActions.open(guild.id, "ROLES"); - GuildSettingsActions.selectRole(id); - }} - icon={PencilIcon} - /> - ); - } - - if (role.icon) { - children.push( - { - openImageModal({ - url: `${location.protocol}//${window.GLOBAL_ENV.CDN_HOST}/role-icons/${role.id}/${role.icon}.${settings.store.roleIconFileFormat}`, - height: 128, - width: 128 - }); - }} - icon={ImageIcon} - /> - - ); - } - - children.push( - ( - loadRoleMembers(guild.id, id)} - renderPopout={popoutProps => ( - - )} - > - {popoutProps => ( -
-
View Role Members
-
- -
-
- )} -
- )} /> - ); + const { before, after } = buildExtraRoleContextMenuItems(role, guild, popoutRef); + children.unshift(...before); + children.push(...after); } } }); diff --git a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx index 031b925d4..00fb79d0e 100644 --- a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx +++ b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx @@ -18,7 +18,8 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Flex } from "@components/Flex"; -import { InfoIcon, OwnerCrownIcon } from "@components/Icons"; +import { InfoIcon, OwnerCrownIcon, RightArrow } from "@components/Icons"; +import { buildExtraRoleContextMenuItems } from "@plugins/betterRoleContext"; import { cl, getGuildPermissionSpecMap, loadGetGuildPermissionSpecMap } from "@plugins/permissionsViewer/utils"; import { copyToClipboard } from "@utils/clipboard"; import { getIntlMessage, getUniqueUsername } from "@utils/discord"; @@ -26,7 +27,7 @@ import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, Mod import { Guild, Role, RoleOrUserPermission, UnicodeEmoji, User } from "@vencord/discord-types"; import { PermissionOverwriteType } from "@vencord/discord-types/enums"; import { findByCodeLazy } from "@webpack"; -import { ContextMenuApi, FluxDispatcher, GuildMemberStore, GuildRoleStore, i18n, Menu, PermissionsBits, ScrollerThin, Text, Tooltip, useEffect, useMemo, UserStore, useState, useStateFromStores } from "@webpack/common"; +import { ContextMenuApi, FluxDispatcher, GuildMemberStore, GuildRoleStore, i18n, Menu, PermissionsBits, ScrollerThin, Text, Tooltip, useEffect, useMemo, useRef, UserStore, useState, useStateFromStores } from "@webpack/common"; import { settings } from ".."; import { PermissionAllowedIcon, PermissionDefaultIcon, PermissionDeniedIcon } from "./icons"; @@ -204,25 +205,42 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea ); } +function IDIcon() { + return ( + + + + + ); +} + function RoleContextMenu({ guild, roleId, onClose }: { guild: Guild; roleId: string; onClose: () => void; }) { + const popoutRef = useRef(null); + const role = GuildRoleStore.getRole(guild.id, roleId); + const { before, after } = buildExtraRoleContextMenuItems(role, guild, popoutRef); + return ( + {before} + { - copyToClipboard(roleId); - }} + icon={IDIcon} + action={() => copyToClipboard(roleId)} /> + {after} + {(settings.store as any).unsafeViewAsRole && ( } action={() => { const role = GuildRoleStore.getRole(guild.id, roleId); if (!role) return;