2023-05-14 21:33:04 -03:00
|
|
|
/*
|
|
|
|
* 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 ErrorBoundary from "@components/ErrorBoundary";
|
2024-05-17 23:01:07 +02:00
|
|
|
import { ExpandableHeader } from "@components/ExpandableHeader";
|
2023-05-14 21:33:04 -03:00
|
|
|
import { classes } from "@utils/misc";
|
2023-11-25 01:32:21 +01:00
|
|
|
import { filters, findBulk, proxyLazyWebpack } from "@webpack";
|
2023-05-28 23:03:06 +03:00
|
|
|
import { i18n, PermissionsBits, Text, Tooltip, useMemo, UserStore } from "@webpack/common";
|
2023-05-14 21:33:04 -03:00
|
|
|
import type { Guild, GuildMember } from "discord-types/general";
|
|
|
|
|
2023-05-22 21:22:25 -03:00
|
|
|
import { PermissionsSortOrder, settings } from "..";
|
2023-05-14 21:33:04 -03:00
|
|
|
import { cl, getPermissionString, getSortedRoles, sortUserRoles } from "../utils";
|
|
|
|
import openRolesAndUsersPermissionsModal, { PermissionType, type RoleOrUserPermission } from "./RolesAndUsersPermissions";
|
|
|
|
|
|
|
|
interface UserPermission {
|
|
|
|
permission: string;
|
|
|
|
roleColor: string;
|
|
|
|
rolePosition: number;
|
|
|
|
}
|
|
|
|
|
|
|
|
type UserPermissions = Array<UserPermission>;
|
|
|
|
|
2024-08-22 20:29:39 -03:00
|
|
|
const { RoleRootClasses, RoleClasses, RoleBorderClasses } = proxyLazyWebpack(() => {
|
|
|
|
const [RoleRootClasses, RoleClasses, RoleBorderClasses] = findBulk(
|
2024-08-28 02:10:20 -03:00
|
|
|
filters.byProps("root", "expandButton", "collapseButton"),
|
2024-08-22 20:29:39 -03:00
|
|
|
filters.byProps("role", "roleCircle", "roleName"),
|
|
|
|
filters.byProps("roleCircle", "dot", "dotBorderColor")
|
|
|
|
) as Record<string, string>[];
|
|
|
|
|
|
|
|
return { RoleRootClasses, RoleClasses, RoleBorderClasses };
|
|
|
|
});
|
|
|
|
|
|
|
|
function UserPermissionsComponent({ guild, guildMember, forceOpen = false }: { guild: Guild; guildMember: GuildMember; forceOpen?: boolean; }) {
|
2023-05-22 21:22:25 -03:00
|
|
|
const stns = settings.use(["permissionsSortOrder"]);
|
2023-05-14 21:33:04 -03:00
|
|
|
|
|
|
|
const [rolePermissions, userPermissions] = useMemo(() => {
|
|
|
|
const userPermissions: UserPermissions = [];
|
|
|
|
|
|
|
|
const userRoles = getSortedRoles(guild, guildMember);
|
|
|
|
|
|
|
|
const rolePermissions: Array<RoleOrUserPermission> = 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 = i18n.Messages.GUILD_OWNER || "Server Owner";
|
|
|
|
userPermissions.push({
|
|
|
|
permission: OWNER,
|
|
|
|
roleColor: "var(--primary-300)",
|
|
|
|
rolePosition: Infinity
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
sortUserRoles(userRoles);
|
|
|
|
|
|
|
|
for (const [permission, bit] of Object.entries(PermissionsBits)) {
|
2023-11-20 23:26:07 -03:00
|
|
|
for (const { permissions, colorString, position } of userRoles) {
|
2023-05-14 21:33:04 -03:00
|
|
|
if ((permissions & bit) === bit) {
|
|
|
|
userPermissions.push({
|
|
|
|
permission: getPermissionString(permission),
|
|
|
|
roleColor: colorString || "var(--primary-300)",
|
|
|
|
rolePosition: position
|
|
|
|
});
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
userPermissions.sort((a, b) => b.rolePosition - a.rolePosition);
|
|
|
|
|
|
|
|
return [rolePermissions, userPermissions];
|
2023-05-22 21:22:25 -03:00
|
|
|
}, [stns.permissionsSortOrder]);
|
2023-05-14 21:33:04 -03:00
|
|
|
|
|
|
|
return (
|
2023-05-28 23:03:06 +03:00
|
|
|
<ExpandableHeader
|
2024-06-26 14:38:50 +02:00
|
|
|
forceOpen={forceOpen}
|
2023-05-28 23:03:06 +03:00
|
|
|
headerText="Permissions"
|
|
|
|
moreTooltipText="Role Details"
|
|
|
|
onMoreClick={() =>
|
|
|
|
openRolesAndUsersPermissionsModal(
|
|
|
|
rolePermissions,
|
|
|
|
guild,
|
|
|
|
guildMember.nick || UserStore.getUser(guildMember.userId).username
|
|
|
|
)
|
|
|
|
}
|
2024-02-09 19:46:10 -03:00
|
|
|
onDropDownClick={state => settings.store.defaultPermissionsDropdownState = !state}
|
2023-05-28 23:03:06 +03:00
|
|
|
defaultState={settings.store.defaultPermissionsDropdownState}
|
|
|
|
buttons={[
|
2023-10-31 23:56:13 +01:00
|
|
|
(<Tooltip text={`Sorting by ${stns.permissionsSortOrder === PermissionsSortOrder.HighestRole ? "Highest Role" : "Lowest Role"}`}>
|
2023-05-28 23:03:06 +03:00
|
|
|
{tooltipProps => (
|
|
|
|
<button
|
|
|
|
{...tooltipProps}
|
|
|
|
className={cl("userperms-sortorder-btn")}
|
|
|
|
onClick={() => {
|
|
|
|
stns.permissionsSortOrder = stns.permissionsSortOrder === PermissionsSortOrder.HighestRole ? PermissionsSortOrder.LowestRole : PermissionsSortOrder.HighestRole;
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<svg
|
|
|
|
width="20"
|
|
|
|
height="20"
|
|
|
|
viewBox="0 96 960 960"
|
|
|
|
transform={stns.permissionsSortOrder === PermissionsSortOrder.HighestRole ? "scale(1 1)" : "scale(1 -1)"}
|
2023-05-14 21:33:04 -03:00
|
|
|
>
|
2023-05-28 23:03:06 +03:00
|
|
|
<path fill="var(--text-normal)" d="M440 896V409L216 633l-56-57 320-320 320 320-56 57-224-224v487h-80Z" />
|
|
|
|
</svg>
|
|
|
|
</button>
|
|
|
|
)}
|
|
|
|
</Tooltip>)
|
|
|
|
]}>
|
|
|
|
{userPermissions.length > 0 && (
|
2024-08-22 20:29:39 -03:00
|
|
|
<div className={classes(RoleRootClasses.root)}>
|
2023-05-14 21:33:04 -03:00
|
|
|
{userPermissions.map(({ permission, roleColor }) => (
|
2024-08-22 20:29:39 -03:00
|
|
|
<div className={classes(RoleClasses.role)}>
|
|
|
|
<div className={RoleClasses.roleRemoveButton}>
|
2023-05-14 21:33:04 -03:00
|
|
|
<span
|
2024-08-22 20:29:39 -03:00
|
|
|
className={classes(RoleBorderClasses.roleCircle, RoleClasses.roleCircle)}
|
2023-05-14 21:33:04 -03:00
|
|
|
style={{ backgroundColor: roleColor }}
|
|
|
|
/>
|
|
|
|
</div>
|
2024-08-22 20:29:39 -03:00
|
|
|
<div className={RoleClasses.roleName}>
|
2023-05-14 21:33:04 -03:00
|
|
|
<Text
|
2024-08-22 20:29:39 -03:00
|
|
|
className={RoleClasses.roleNameOverflow}
|
2023-05-14 21:33:04 -03:00
|
|
|
variant="text-xs/medium"
|
|
|
|
>
|
|
|
|
{permission}
|
|
|
|
</Text>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
)}
|
2023-05-28 23:03:06 +03:00
|
|
|
</ExpandableHeader>
|
2023-05-14 21:33:04 -03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export default ErrorBoundary.wrap(UserPermissionsComponent, { noop: true });
|