/* * 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 ErrorBoundary from "@components/ErrorBoundary"; import { getIntlMessage } from "@utils/discord"; import { classes } from "@utils/misc"; import type { Guild, GuildMember } from "@vencord/discord-types"; import { filters, findBulk, proxyLazyWebpack } from "@webpack"; import { PermissionsBits, Text, Tooltip, useMemo, UserStore } from "@webpack/common"; import { PermissionsSortOrder, settings } from ".."; import { cl, getGuildPermissionSpecMap, getSortedRoles, sortUserRoles } from "../utils"; import openRolesAndUsersPermissionsModal, { PermissionType, type RoleOrUserPermission } from "./RolesAndUsersPermissions"; interface UserPermission { permission: string; roleName: string; roleColor: string; rolePosition: number; } type UserPermissions = Array; const { RoleRootClasses, RoleClasses, RoleBorderClasses } = proxyLazyWebpack(() => { const [RoleRootClasses, RoleClasses, RoleBorderClasses] = findBulk( filters.byProps("root", "expandButton", "collapseButton"), filters.byProps("role", "roleCircle", "roleName"), filters.byProps("roleCircle", "dot", "dotBorderColor") ) as Record[]; return { RoleRootClasses, 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 = getSortedRoles(guild, guildMember); const rolePermissions: Array = userRoles.map(role => ({ type: PermissionType.Role, ...role })); if (guild.ownerId === guildMember.userId) { rolePermissions.push({ type: PermissionType.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 });