clean up messy code
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import * as Popover from '@radix-ui/react-popover';
|
||||
import { memo } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
import { WorldIcon } from '@shared/icons';
|
||||
import { Image } from '@shared/image';
|
||||
import { NIP05 } from '@shared/nip05';
|
||||
|
||||
@@ -9,77 +10,172 @@ import { formatCreatedAt } from '@utils/createdAt';
|
||||
import { useProfile } from '@utils/hooks/useProfile';
|
||||
import { displayNpub } from '@utils/shortenKey';
|
||||
|
||||
export function User({
|
||||
export const User = memo(function User({
|
||||
pubkey,
|
||||
time,
|
||||
size,
|
||||
isRepost = false,
|
||||
isChat = false,
|
||||
variant = 'default',
|
||||
embedProfile,
|
||||
}: {
|
||||
pubkey: string;
|
||||
time: number;
|
||||
size?: string;
|
||||
isRepost?: boolean;
|
||||
isChat?: boolean;
|
||||
time?: number;
|
||||
variant?: 'default' | 'simple' | 'mention' | 'repost' | 'chat' | 'large' | 'thread';
|
||||
embedProfile?: string;
|
||||
}) {
|
||||
const { status, user } = useProfile(pubkey);
|
||||
|
||||
const createdAt = formatCreatedAt(time, isChat);
|
||||
const avatarWidth = size === 'small' ? 'w-6' : 'w-11';
|
||||
const avatarHeight = size === 'small' ? 'h-6' : 'h-11';
|
||||
const { status, user } = useProfile(pubkey, embedProfile);
|
||||
const createdAt = time ? formatCreatedAt(time, variant === 'chat') : 0;
|
||||
|
||||
if (status === 'loading') {
|
||||
return (
|
||||
<div
|
||||
className={`relative flex gap-3 ${
|
||||
size === 'small' ? 'items-center' : 'items-start'
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className={`${avatarWidth} ${avatarHeight} ${
|
||||
size === 'small' ? 'rounded' : 'rounded-lg'
|
||||
} relative z-10 shrink-0 animate-pulse overflow-hidden bg-white/10 backdrop-blur-xl`}
|
||||
/>
|
||||
<div className="flex flex-wrap items-baseline gap-1">
|
||||
if (variant === 'mention') {
|
||||
return (
|
||||
<div className="relative flex items-center gap-3">
|
||||
<div className="relative z-10 h-6 w-6 shrink-0 animate-pulse overflow-hidden rounded bg-white/10 backdrop-blur-xl" />
|
||||
<div className="h-3.5 w-36 animate-pulse rounded bg-white/10 backdrop-blur-xl" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative flex items-start gap-3">
|
||||
<div className="relative z-10 h-11 w-11 shrink-0 animate-pulse overflow-hidden rounded-lg bg-white/10 backdrop-blur-xl" />
|
||||
<div className="h-3.5 w-36 animate-pulse rounded bg-white/10 backdrop-blur-xl" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (variant === 'mention') {
|
||||
return (
|
||||
<div className="relative z-10 flex items-center gap-2">
|
||||
<button type="button" className="relative z-40 h-6 w-6 shrink-0 overflow-hidden">
|
||||
<Image
|
||||
src={user?.picture || user?.image}
|
||||
alt={pubkey}
|
||||
className="h-6 w-6 rounded object-cover"
|
||||
/>
|
||||
</button>
|
||||
<div className="flex flex-1 items-baseline gap-2">
|
||||
<h5 className="max-w-[10rem] truncate font-semibold leading-none text-white">
|
||||
{user?.display_name || user?.name || displayNpub(pubkey, 16)}
|
||||
</h5>
|
||||
<span className="leading-none text-white/50">·</span>
|
||||
<span className="leading-none text-white/50">{createdAt}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (variant === 'large') {
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col gap-2.5">
|
||||
<Image
|
||||
src={user?.picture || user?.image}
|
||||
alt={pubkey}
|
||||
className="h-14 w-14 shrink-0 rounded-lg object-cover"
|
||||
/>
|
||||
<div className="flex h-full flex-col items-start justify-between">
|
||||
<div className="flex flex-col items-start gap-1 text-start">
|
||||
<p className="max-w-[15rem] truncate text-lg font-semibold leading-none text-white">
|
||||
{user?.name || user?.display_name}
|
||||
</p>
|
||||
<p className="line-clamp-6 break-all text-white/70">
|
||||
{user?.about || user?.bio || 'No bio'}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
{user?.website ? (
|
||||
<Link
|
||||
to={user?.website}
|
||||
target="_blank"
|
||||
className="inline-flex items-center gap-2 text-sm text-white/70"
|
||||
>
|
||||
<WorldIcon className="h-4 w-4" />
|
||||
<p className="max-w-[10rem] truncate">{user.website}</p>
|
||||
</Link>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (variant === 'simple') {
|
||||
return (
|
||||
<div className="flex items-center gap-2.5">
|
||||
<Image
|
||||
src={user?.picture || user?.image}
|
||||
alt={pubkey}
|
||||
className="h-12 w-12 shrink-0 rounded-lg object-cover"
|
||||
/>
|
||||
<div className="flex w-full flex-col gap-1">
|
||||
<h3 className="max-w-[15rem] truncate font-medium leading-none text-white">
|
||||
{user?.name || user?.display_name}
|
||||
</h3>
|
||||
<p className="text-sm leading-none text-white/70">
|
||||
{user?.nip05 || user?.username || displayNpub(pubkey, 16)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (variant === 'repost') {
|
||||
return (
|
||||
<div className="flex gap-3">
|
||||
<Image
|
||||
src={user?.picture || user?.image}
|
||||
alt={pubkey}
|
||||
className="relative z-20 inline-block h-11 w-11 rounded-lg"
|
||||
/>
|
||||
<div className="inline-flex items-baseline gap-1">
|
||||
<h5 className="max-w-[15rem] truncate font-semibold leading-none text-white">
|
||||
{user?.display_name || user?.name || displayNpub(pubkey, 16)}
|
||||
</h5>
|
||||
<span className="font-semibold text-fuchsia-500">reposted</span>
|
||||
<span className="leading-none text-white/50">·</span>
|
||||
<span className="leading-none text-white/50">{createdAt}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (variant === 'thread') {
|
||||
return (
|
||||
<div className="flex items-center gap-3">
|
||||
<Image
|
||||
src={user?.picture || user?.image}
|
||||
alt={pubkey}
|
||||
className="relative z-20 inline-block h-11 w-11 rounded-lg"
|
||||
/>
|
||||
<div className="flex flex-1 flex-col gap-2">
|
||||
<h5 className="max-w-[15rem] truncate font-semibold leading-none text-white">
|
||||
{user?.display_name || user?.name}
|
||||
</h5>
|
||||
<div className="inline-flex items-center gap-2">
|
||||
<span className="leading-none text-white/50">{createdAt}</span>
|
||||
<span className="leading-none text-white/50">·</span>
|
||||
<span className="leading-none text-white/50">{displayNpub(pubkey, 16)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Popover.Root>
|
||||
<div
|
||||
className={twMerge(
|
||||
'relative z-10 flex',
|
||||
size === 'small' ? 'items-center gap-2' : 'items-start gap-3'
|
||||
)}
|
||||
>
|
||||
<div className="relative z-10 flex items-start gap-3">
|
||||
<Popover.Trigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className={`${avatarWidth} ${avatarHeight} relative z-40 shrink-0 overflow-hidden`}
|
||||
className="relative z-40 h-11 w-11 shrink-0 overflow-hidden"
|
||||
>
|
||||
<Image
|
||||
src={user?.picture || user?.image}
|
||||
alt={pubkey}
|
||||
className={twMerge(
|
||||
`object-cover ${avatarWidth} ${avatarHeight}`,
|
||||
size === 'small' ? 'rounded' : 'rounded-lg',
|
||||
isRepost ? 'ring-1 ring-black' : ''
|
||||
)}
|
||||
className="h-11 w-11 rounded-lg object-cover"
|
||||
/>
|
||||
</button>
|
||||
</Popover.Trigger>
|
||||
<div
|
||||
className={twMerge('flex flex-1 items-baseline gap-2', isRepost ? 'mt-4' : '')}
|
||||
>
|
||||
<h5
|
||||
className={twMerge(
|
||||
'truncate font-semibold leading-none text-white',
|
||||
size === 'small' ? 'max-w-[10rem]' : 'max-w-[15rem]'
|
||||
)}
|
||||
>
|
||||
<div className="flex flex-1 items-baseline gap-2">
|
||||
<h5 className="max-w-[15rem] truncate font-semibold leading-none text-white">
|
||||
{user?.display_name || user?.name || displayNpub(pubkey, 16)}
|
||||
</h5>
|
||||
<span className="leading-none text-white/50">·</span>
|
||||
@@ -139,4 +235,4 @@ export function User({
|
||||
</Popover.Portal>
|
||||
</Popover.Root>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user