2023-01-16 17:31:17 +00:00
|
|
|
import "./Avatar.css";
|
2023-03-03 14:30:31 +00:00
|
|
|
|
2023-06-08 10:45:23 +00:00
|
|
|
import type { UserMetadata } from "@snort/system";
|
2023-10-16 14:48:56 +00:00
|
|
|
import classNames from "classnames";
|
2024-01-04 17:01:18 +00:00
|
|
|
import { ReactNode, useMemo } from "react";
|
2023-03-03 14:30:31 +00:00
|
|
|
|
2024-01-04 17:01:18 +00:00
|
|
|
import { ProxyImg } from "@/Components/ProxyImg";
|
|
|
|
import { defaultAvatar, getDisplayName } from "@/Utils";
|
2023-01-16 17:31:17 +00:00
|
|
|
|
2023-05-15 10:53:03 +00:00
|
|
|
interface AvatarProps {
|
2023-08-24 15:54:20 +00:00
|
|
|
pubkey: string;
|
2023-05-15 10:53:03 +00:00
|
|
|
user?: UserMetadata;
|
|
|
|
onClick?: () => void;
|
|
|
|
size?: number;
|
2023-08-21 13:58:57 +00:00
|
|
|
image?: string;
|
2023-09-14 11:31:17 +00:00
|
|
|
imageOverlay?: ReactNode;
|
2023-09-18 10:32:34 +00:00
|
|
|
icons?: ReactNode;
|
2023-11-29 12:36:24 +00:00
|
|
|
showTitle?: boolean;
|
2023-10-05 12:08:25 +00:00
|
|
|
className?: string;
|
2023-05-15 10:53:03 +00:00
|
|
|
}
|
2023-09-18 10:32:34 +00:00
|
|
|
|
2023-11-29 12:36:24 +00:00
|
|
|
const Avatar = ({
|
|
|
|
pubkey,
|
|
|
|
user,
|
|
|
|
size,
|
|
|
|
onClick,
|
|
|
|
image,
|
|
|
|
imageOverlay,
|
|
|
|
icons,
|
|
|
|
className,
|
|
|
|
showTitle = true,
|
|
|
|
}: AvatarProps) => {
|
2024-03-12 22:21:04 +00:00
|
|
|
const defaultImg = defaultAvatar(pubkey);
|
2024-01-01 22:25:44 +00:00
|
|
|
const url = useMemo(() => {
|
2024-03-12 22:21:04 +00:00
|
|
|
if((image?.length ?? 0) > 0) return image;
|
|
|
|
if((user?.picture?.length ?? 0) > 0) return user?.picture;
|
|
|
|
return defaultImg;
|
2023-11-28 12:20:35 +00:00
|
|
|
}, [user, image, pubkey]);
|
|
|
|
|
|
|
|
const s = size ?? 120;
|
|
|
|
const style = {} as React.CSSProperties;
|
2023-09-22 10:24:08 +00:00
|
|
|
if (size) {
|
2023-11-28 12:20:35 +00:00
|
|
|
style.width = `${size}px`;
|
|
|
|
style.height = `${size}px`;
|
2023-09-22 10:24:08 +00:00
|
|
|
}
|
2023-11-28 12:20:35 +00:00
|
|
|
|
2023-02-07 20:04:50 +00:00
|
|
|
const domain = user?.nip05 && user.nip05.split("@")[1];
|
2024-03-12 22:21:04 +00:00
|
|
|
const isDefault = url === defaultImg;
|
2023-08-19 21:59:49 +00:00
|
|
|
return (
|
|
|
|
<div
|
|
|
|
onClick={onClick}
|
|
|
|
style={style}
|
2023-11-29 10:53:17 +00:00
|
|
|
className={classNames(
|
|
|
|
"avatar relative flex items-center justify-center",
|
|
|
|
{ "with-overlay": imageOverlay },
|
2024-03-12 22:21:04 +00:00
|
|
|
{ "outline outline-2 outline-nostr-purple m-[2px]": isDefault },
|
2023-11-29 10:53:17 +00:00
|
|
|
className,
|
|
|
|
)}
|
2023-08-19 21:59:49 +00:00
|
|
|
data-domain={domain?.toLowerCase()}
|
2023-11-29 12:36:24 +00:00
|
|
|
title={showTitle ? getDisplayName(user, "") : undefined}>
|
2023-11-29 10:30:12 +00:00
|
|
|
<ProxyImg
|
|
|
|
className="rounded-full object-cover aspect-square"
|
|
|
|
src={url}
|
|
|
|
size={s}
|
|
|
|
alt={getDisplayName(user, "")}
|
|
|
|
promptToLoadDirectly={false}
|
|
|
|
/>
|
2023-09-18 10:32:34 +00:00
|
|
|
{icons && <div className="icons">{icons}</div>}
|
2023-09-14 11:31:17 +00:00
|
|
|
{imageOverlay && <div className="overlay">{imageOverlay}</div>}
|
|
|
|
</div>
|
2023-08-19 21:59:49 +00:00
|
|
|
);
|
2023-02-07 20:04:50 +00:00
|
|
|
};
|
2023-01-16 17:31:17 +00:00
|
|
|
|
2023-02-07 20:04:50 +00:00
|
|
|
export default Avatar;
|