diff --git a/src/plugins/serverProfile/GuildProfileModal.tsx b/src/plugins/serverProfile/GuildProfileModal.tsx index 7dc882f9..40fb72b2 100644 --- a/src/plugins/serverProfile/GuildProfileModal.tsx +++ b/src/plugins/serverProfile/GuildProfileModal.tsx @@ -7,16 +7,17 @@ import "./styles.css"; import { classNameFactory } from "@api/Styles"; -import { openImageModal } from "@utils/discord"; +import { openImageModal, openUserProfile } from "@utils/discord"; import { classes } from "@utils/misc"; import { ModalRoot, ModalSize, openModal } from "@utils/modal"; -import { useAwaiter } from "@utils/react"; -import { findByPropsLazy } from "@webpack"; -import { Forms, GuildChannelStore, GuildMemberStore, Parser, SnowflakeUtils, TabBar, UserUtils, useState } from "@webpack/common"; +import { LazyComponent, useAwaiter } from "@utils/react"; +import { findByCode, findByPropsLazy } from "@webpack"; +import { FluxDispatcher, Forms, GuildChannelStore, GuildMemberStore, Parser, PresenceStore, RelationshipStore, ScrollerThin, SnowflakeUtils, TabBar, useEffect, UserStore, UserUtils, useState, useStateFromStores } from "@webpack/common"; import { Guild, User } from "discord-types/general"; const IconUtils = findByPropsLazy("getGuildBannerURL"); const IconClasses = findByPropsLazy("icon", "acronym", "childWrapper"); +const UserRow = LazyComponent(() => findByCode(".listDiscriminator")); const cl = classNameFactory("vc-gp-"); @@ -49,7 +50,17 @@ interface GuildProps { guild: Guild; } +const fetched = { + friends: false, + blocked: false +}; + function GuildProfileModal({ guild }: GuildProps) { + useEffect(() => { + fetched.friends = false; + fetched.blocked = false; + }, []); + const [currentTab, setCurrentTab] = useState("ServerInfo"); const Tab = Tabs[currentTab].component; @@ -175,9 +186,54 @@ function ServerInfoTab({ guild }: GuildProps) { } function FriendsTab({ guild }: GuildProps) { - return null; + return UserList("friends", guild, RelationshipStore.getFriendIDs()); } function BlockedUsersTab({ guild }: GuildProps) { - return null; + const blockedIds = Object.keys(RelationshipStore.getRelationships()).filter(id => RelationshipStore.isBlocked(id)); + return UserList("blocked", guild, blockedIds); +} + +function UserList(type: "friends" | "blocked", guild: Guild, ids: string[]) { + const missing = [] as string[]; + const members = [] as string[]; + + for (const id of ids) { + if (GuildMemberStore.isMember(guild.id, id)) + members.push(id); + else + missing.push(id); + } + + // Used for side effects (rerender on member request success) + useStateFromStores( + [GuildMemberStore], + () => GuildMemberStore.getMemberIds(guild.id), + null, + (old, curr) => old.length === curr.length + ); + + useEffect(() => { + if (!fetched[type] && missing.length) { + fetched[type] = true; + FluxDispatcher.dispatch({ + type: "GUILD_MEMBERS_REQUEST", + guildIds: [guild.id], + userIds: missing + }); + } + }, []); + + return ( + + {members.map(id => + openUserProfile(id)} + onContextMenu={() => { }} + /> + )} + + ); } diff --git a/src/plugins/serverProfile/styles.css b/src/plugins/serverProfile/styles.css index bea0c189..39a91f9c 100644 --- a/src/plugins/serverProfile/styles.css +++ b/src/plugins/serverProfile/styles.css @@ -1,3 +1,6 @@ +.vc-gp-content { +} + .vc-gp-root { height: 100%; user-select: text; @@ -78,3 +81,12 @@ border-radius: 50%; cursor: pointer; } + +.vc-gp-scroller { + width: 100%; + max-height: 500px; +} + +.vc-gp-scroller [class^=listRow]:hover { + background-color: var(--background-modifier-hover); +}