/* * Vencord, a Discord client mod * Copyright (c) 2024 Vendicated and contributors * SPDX-License-Identifier: GPL-3.0-or-later */ import ErrorBoundary from "@components/ErrorBoundary"; import { InfoIcon } from "@components/Icons"; import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; import { findByCodeLazy, findExportedComponentLazy } from "@webpack"; import { Constants, GuildChannelStore, GuildMemberStore, GuildStore, Parser, RestAPI, ScrollerThin, Text, Tooltip, useEffect, UserStore, useState } from "@webpack/common"; import { UnicodeEmoji } from "@webpack/types"; import type { Role } from "discord-types/general"; import { cl, GuildUtils } from "./utils"; type GetRoleIconData = (role: Role, size: number) => { customIconSrc?: string; unicodeEmoji?: UnicodeEmoji; }; const ThreeDots = findExportedComponentLazy("Dots", "AnimatedDots"); const getRoleIconData: GetRoleIconData = findByCodeLazy("convertSurrogateToName", "customIconSrc", "unicodeEmoji"); function getRoleIconSrc(role: Role) { const icon = getRoleIconData(role, 20); if (!icon) return; const { customIconSrc, unicodeEmoji } = icon; return customIconSrc ?? unicodeEmoji?.url; } function MembersContainer({ guildId, roleId }: { guildId: string; roleId: string; }) { const channelId = GuildChannelStore.getChannels(guildId).SELECTABLE[0].channel.id; // RMC: RoleMemberCounts const [RMC, setRMC] = useState({}); useEffect(() => { let loading = true; const interval = setInterval(async () => { try { await RestAPI.get({ url: Constants.Endpoints.GUILD_ROLE_MEMBER_COUNTS(guildId) }).then(x => { if (x.ok) setRMC(x.body); clearInterval(interval); }); } catch (error) { console.error("Error fetching member counts", error); } }, 1000); return () => { loading = false; }; }, []); let usersInRole = []; const [rolesFetched, setRolesFetched] = useState(Array); useEffect(() => { if (!rolesFetched.includes(roleId)) { const interval = setInterval(async () => { try { const response = await RestAPI.get({ url: Constants.Endpoints.GUILD_ROLE_MEMBER_IDS(guildId, roleId), }); ({ body: usersInRole } = response); await GuildUtils.requestMembersById(guildId, usersInRole, !1); setRolesFetched([...rolesFetched, roleId]); clearInterval(interval); } catch (error) { console.error("Error fetching members:", error); } }, 1200); return () => clearInterval(interval); } }, [roleId]); // Fetch roles const [members, setMembers] = useState(GuildMemberStore.getMembers(guildId)); useEffect(() => { const interval = setInterval(async () => { if (usersInRole) { const guildMembers = GuildMemberStore.getMembers(guildId); const storedIds = guildMembers.map(user => user.userId); usersInRole.every(id => storedIds.includes(id)) && clearInterval(interval); if (guildMembers !== members) { setMembers(GuildMemberStore.getMembers(guildId)); } } }, 500); return () => clearInterval(interval); }, [roleId, rolesFetched]); const roleMembers = members.filter(x => x.roles.includes(roleId)).map(x => UserStore.getUser(x.userId)); return (
{roleMembers.length} loaded / {RMC[roleId] || 0} members with this role
{props => }
{roleMembers.map(x => { return (
{Parser.parse(`<@${x.id}>`, true, { channelId, viewingChannelId: channelId })}
); })} { (Object.keys(RMC).length === 0) ? (
) : !RMC[roleId] ? ( No member found with this role ) : RMC[roleId] === roleMembers.length ? ( <>
All members loaded ) : rolesFetched.includes(roleId) ? ( <>
All cached members loaded ) : (
) }
); } function InRoleModal({ guildId, props, roleId }: { guildId: string; props: ModalProps; roleId: string; }) { const roleObj = GuildStore.getRoles(guildId); const roles = Object.keys(roleObj).map(key => roleObj[key]).sort((a, b) => b.position - a.position); const [selectedRole, selectRole] = useState(roles.find(x => x.id === roleId) || roles[0]); return ( View members with role
{roles.map((role, index) => { if (role.id === guildId) return; const roleIconSrc = role != null ? getRoleIconSrc(role) : undefined; return (
selectRole(roles[index])} role="button" tabIndex={0} key={role.id} >
{ roleIconSrc != null && ( ) } {role?.name || "Unknown role"}
); })}
); } export function showInRoleModal(guildId: string, roleId: string) { openModal(props => ); }