/* * 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 . */ import { BaseText } from "@components/BaseText"; import ErrorBoundary from "@components/ErrorBoundary"; import { HeadingTertiary } from "@components/Heading"; import { cl, getGuildPermissionSpecMap, getSortedRolesForMember, sortUserRoles } from "@plugins/permissionsViewer/utils"; import { getIntlMessage } from "@utils/discord"; import { classes } from "@utils/misc"; import type { Guild, GuildMember, RoleOrUserPermission } from "@vencord/discord-types"; import { PermissionOverwriteType } from "@vencord/discord-types/enums"; import { filters, findBulk, proxyLazyWebpack } from "@webpack"; import { PermissionsBits, Tooltip, useMemo, UserStore } from "@webpack/common"; import { PermissionsSortOrder, settings } from ".."; import openRolesAndUsersPermissionsModal from "./RolesAndUsersPermissions"; interface UserPermission { permission: string; roleName: string; roleColor: string; rolePosition: number; } type UserPermissions = Array; const { RoleClasses, RoleBorderClasses } = proxyLazyWebpack(() => { const [RoleClasses, RoleBorderClasses] = findBulk( filters.byProps("root", "role", "roleRemoveButton", "roleName"), filters.byProps("roleCircle", "dotBorderColor") ) as Record[]; return { RoleClasses, RoleBorderClasses }; }); interface FakeRoleProps extends React.HTMLAttributes { text: string; color: string; } function FakeRole({ text, color, ...props }: FakeRoleProps) { return (
{text}
); } interface GrantedByTooltipProps { roleName: string; roleColor: string; } function GrantedByTooltip({ roleName, roleColor }: GrantedByTooltipProps) { return ( <> Granted By ); } function UserPermissionsComponent({ guild, guildMember, closePopout }: { guild: Guild; guildMember: GuildMember; closePopout: () => void; }) { const { permissionsSortOrder } = settings.use(["permissionsSortOrder"]); const guildPermissionSpecMap = useMemo(() => getGuildPermissionSpecMap(guild), [guild.id]); const [rolePermissions, userPermissions] = useMemo(() => { const userPermissions: UserPermissions = []; const userRoles = getSortedRolesForMember(guild, guildMember); const rolePermissions: Array = userRoles.map(role => ({ type: PermissionOverwriteType.ROLE, ...role })); if (guild.ownerId === guildMember.userId) { rolePermissions.push({ type: PermissionOverwriteType.OWNER, permissions: Object.values(PermissionsBits).reduce((prev, curr) => prev | curr, 0n) }); const OWNER = getIntlMessage("GUILD_OWNER") ?? "Server Owner"; userPermissions.push({ permission: OWNER, roleName: "Owner", roleColor: "var(--primary-300)", rolePosition: Infinity }); } sortUserRoles(userRoles); for (const bit of Object.values(PermissionsBits)) { for (const { permissions, colorString, position, name } of userRoles) { if ((permissions & bit) === bit) { userPermissions.push({ permission: guildPermissionSpecMap[String(bit)].title, roleName: name, roleColor: colorString || "var(--primary-300)", rolePosition: position }); break; } } } userPermissions.sort((a, b) => b.rolePosition - a.rolePosition); return [rolePermissions, userPermissions]; }, [permissionsSortOrder]); return
Permissions
{tooltipProps => (
{ settings.store.permissionsSortOrder = permissionsSortOrder === PermissionsSortOrder.HighestRole ? PermissionsSortOrder.LowestRole : PermissionsSortOrder.HighestRole; }} >
)}
{tooltipProps => (
{ closePopout(); openRolesAndUsersPermissionsModal(rolePermissions, guild, guildMember.nick || UserStore.getUser(guildMember.userId).username); }} >
)}
{userPermissions.length > 0 && (
{userPermissions.map(({ permission, roleColor, roleName }) => ( } tooltipClassName={cl("granted-by-container")} tooltipContentClassName={cl("granted-by-content")} > {tooltipProps => ( )} ))}
)}
; } export default ErrorBoundary.wrap(UserPermissionsComponent, { noop: true });