import { ListUl } from "@styled-icons/boxicons-regular"; import { Envelope, Edit, UserPlus, UserX, Group, InfoCircle, } from "@styled-icons/boxicons-solid"; import { observer } from "mobx-react-lite"; import { Link, useHistory } from "react-router-dom"; import { UserPermission, API } from "revolt.js"; import styles from "./UserProfile.module.scss"; import { Localizer, Text } from "preact-i18n"; import { useContext, useEffect, useLayoutEffect, useState } from "preact/hooks"; import { noop } from "../../../lib/js"; import ChannelIcon from "../../../components/common/ChannelIcon"; import ServerIcon from "../../../components/common/ServerIcon"; import Tooltip from "../../../components/common/Tooltip"; import UserBadges from "../../../components/common/user/UserBadges"; import UserIcon from "../../../components/common/user/UserIcon"; import { Username } from "../../../components/common/user/UserShort"; import UserStatus from "../../../components/common/user/UserStatus"; import Button from "../../../components/ui/Button"; 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?: API.UserProfile; } export const UserProfile = observer( ({ user_id, onClose, dummy, dummyProfile }: Props) => { const { openScreen, writeClipboard } = useIntermediate(); const [profile, setProfile] = useState< undefined | null | API.UserProfile >(undefined); const [mutual, setMutual] = useState< undefined | null | API.MutualResponse >(undefined); const [isPublicBot, setIsPublicBot] = useState< undefined | null | boolean >(); 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); if (typeof isPublicBot !== "undefined") setIsPublicBot(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).catch(noop); } } }, [profile, status, dummy, user]); useEffect(() => { if ( status === ClientStatus.ONLINE && user.bot && typeof isPublicBot === "undefined" ) { setIsPublicBot(null); client.bots .fetchPublic(user._id) .then(() => setIsPublicBot(true)) .catch(noop); } }, [isPublicBot, status, user, client.bots]); const backgroundURL = profile && client.generateFileURL( profile.background as any, { 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 && ( )}
{isPublicBot && ( )} {user.relationship === "Friend" && ( }> { onClose?.(); history.push(`/open/${user_id}`); }}> )} {user.relationship === "User" && !dummy && ( { onClose?.(); history.push(`/settings/profile`); }}> )} {!user.bot && flags != 2 && flags != 4 && (user.relationship === "Incoming" || user.relationship === "None" || user.relationship === null) && ( user.addFriend()}> )} {user.relationship === "Outgoing" && ( user.removeFriend()}> )}
setTab("profile")}>
{user.relationship !== "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 && ( )} {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}
), )}
))}
); }, );