import { Money } from "@styled-icons/boxicons-regular"; import { Envelope, Edit, UserPlus, Shield } from "@styled-icons/boxicons-solid"; import { observer } from "mobx-react-lite"; import { Link, useHistory } from "react-router-dom"; import { Profile, RelationshipStatus } from "revolt-api/types/Users"; import { UserPermission } from "revolt.js/dist/api/permissions"; import { Route } from "revolt.js/dist/api/routes"; import styles from "./UserProfile.module.scss"; import { Localizer, Text } from "preact-i18n"; import { useContext, useEffect, useLayoutEffect, useState } from "preact/hooks"; import ChannelIcon from "../../../components/common/ChannelIcon"; import ServerIcon from "../../../components/common/ServerIcon"; import Tooltip from "../../../components/common/Tooltip"; import UserIcon from "../../../components/common/user/UserIcon"; import { Username } from "../../../components/common/user/UserShort"; import UserStatus from "../../../components/common/user/UserStatus"; import IconButton from "../../../components/ui/IconButton"; import Modal from "../../../components/ui/Modal"; import Overline from "../../../components/ui/Overline"; import Preloader from "../../../components/ui/Preloader"; import Markdown from "../../../components/markdown/Markdown"; import { ClientStatus, StatusContext, useClient, } from "../../revoltjs/RevoltClient"; import { useIntermediate } from "../Intermediate"; interface Props { user_id: string; dummy?: boolean; onClose?: () => void; dummyProfile?: Profile; } enum Badges { Developer = 1, Translator = 2, Supporter = 4, ResponsibleDisclosure = 8, EarlyAdopter = 256, } export const UserProfile = observer( ({ user_id, onClose, dummy, dummyProfile }: Props) => { const { openScreen, writeClipboard } = useIntermediate(); const [profile, setProfile] = useState( undefined, ); const [mutual, setMutual] = useState< undefined | null | Route<"GET", "/users/id/mutual">["response"] >(undefined); const history = useHistory(); const client = useClient(); const status = useContext(StatusContext); const [tab, setTab] = useState("profile"); const user = client.users.get(user_id); if (!user) { if (onClose) useEffect(onClose, []); return null; } const users = mutual?.users.map((id) => client.users.get(id)); const mutualGroups = [...client.channels.values()].filter( (channel) => channel?.channel_type === "Group" && channel.recipient_ids!.includes(user_id), ); const mutualServers = mutual?.servers.map((id) => client.servers.get(id), ); useLayoutEffect(() => { if (!user_id) return; if (typeof profile !== "undefined") setProfile(undefined); if (typeof mutual !== "undefined") setMutual(undefined); // eslint-disable-next-line }, [user_id]); useEffect(() => { if (dummy) { setProfile(dummyProfile); } }, [dummy, dummyProfile]); useEffect(() => { if (dummy) return; if ( status === ClientStatus.ONLINE && typeof mutual === "undefined" ) { setMutual(null); user.fetchMutual().then(setMutual); } }, [mutual, status, dummy, user]); useEffect(() => { if (dummy) return; if ( status === ClientStatus.ONLINE && typeof profile === "undefined" ) { setProfile(null); if (user.permission & UserPermission.ViewProfile) { user.fetchProfile().then(setProfile); } } }, [profile, status, dummy, user]); const backgroundURL = profile && client.generateFileURL(profile.background, { width: 1000 }, true); const badges = user.badges ?? 0; const flags = user.flags ?? 0; return (
user.avatar && openScreen({ id: "image_viewer", attachment: user.avatar, }) } />
writeClipboard(user.username) }> @{user.username} {user.status?.text && ( )}
{user.relationship === RelationshipStatus.Friend && ( }> { onClose?.(); history.push(`/open/${user_id}`); }}> )} {user.relationship === RelationshipStatus.User && ( { onClose?.(); if (dummy) return; history.push(`/settings/profile`); }}> )} {(user.relationship === RelationshipStatus.Incoming || user.relationship === RelationshipStatus.None) && ( user.addFriend()}> )}
setTab("profile")}>
{user.relationship !== RelationshipStatus.User && ( <>
setTab("friends")}>
setTab("groups")}>
setTab("servers")}>
)}
{tab === "profile" && (
{!( profile?.content || badges > 0 || flags > 0 || user.bot ) && (
)} {flags & 1 ? ( /** ! FIXME: i18n this area */ User is suspended ) : undefined} {flags & 2 ? ( User deleted their account ) : undefined} {flags & 4 ? ( User is banned ) : undefined} {user.bot ? ( <>
bot owner
user.bot && openScreen({ id: "profile", user_id: user.bot.owner, }) } className={styles.entry} key={user.bot.owner}>
) : undefined} {badges > 0 && (
)} {badges > 0 && (
{badges & Badges.Developer ? ( }> ) : ( <> )} {badges & Badges.Translator ? ( }> ) : ( <> )} {badges & Badges.EarlyAdopter ? ( }> ) : ( <> )} {badges & Badges.Supporter ? ( }> ) : ( <> )} {badges & Badges.ResponsibleDisclosure ? ( }> ) : ( <> )}
)} {profile?.content && (
)} {/*
*/}
)} {tab === "friends" && (users ? (
{users.length === 0 ? (
) : ( users.map( (x) => x && (
openScreen({ id: "profile", user_id: x._id, }) } className={styles.entry} key={x._id}> {x.username}
), ) )}
) : ( ))} {tab === "groups" && (
{mutualGroups.length === 0 ? (
) : ( mutualGroups.map( (x) => x?.channel_type === "Group" && (
{x.name}
), ) )}
)} {tab === "servers" && (
{!mutualServers || mutualServers.length === 0 ? (
) : ( mutualServers.map( (x) => x && (
{x.name}
), ) )}
)}
); }, );