65 lines
2.2 KiB
TypeScript
65 lines
2.2 KiB
TypeScript
import { Image } from '@shared/image';
|
|
|
|
import { useOpenGraph } from '@utils/hooks/useOpenGraph';
|
|
|
|
export function LinkPreview({ urls }: { urls: string[] }) {
|
|
const { status, data, error } = useOpenGraph(urls[0]);
|
|
const domain = new URL(urls[0]);
|
|
|
|
return (
|
|
<div className="mb-2 mt-3 max-w-[420px] overflow-hidden rounded-lg bg-zinc-800">
|
|
{status === 'loading' ? (
|
|
<div className="flex flex-col">
|
|
<div className="h-44 w-full animate-pulse bg-zinc-700" />
|
|
<div className="flex flex-col gap-2 px-3 py-3">
|
|
<div className="h-3 w-2/3 animate-pulse rounded bg-zinc-700" />
|
|
<div className="h-3 w-3/4 animate-pulse rounded bg-zinc-700" />
|
|
<span className="mt-2.5 text-sm leading-none text-zinc-500">
|
|
{domain.hostname}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<a
|
|
className="flex flex-col rounded-lg border-t border-zinc-700/50"
|
|
href={urls[0]}
|
|
target="_blank"
|
|
rel="noreferrer"
|
|
>
|
|
{error ? (
|
|
<div className="px-3 py-3">
|
|
<p className="line-clamp-3 break-all text-sm text-zinc-400">
|
|
Can't fetch open graph, click to open webpage
|
|
</p>
|
|
</div>
|
|
) : (
|
|
<>
|
|
{data.images?.[0] && (
|
|
<Image
|
|
src={data.images?.[0] || 'https://void.cat/d/XTmrMkpid8DGLjv1AzdvcW'}
|
|
fallback="https://void.cat/d/XTmrMkpid8DGLjv1AzdvcW"
|
|
alt={urls[0]}
|
|
className="h-44 w-full rounded-t-lg object-cover"
|
|
/>
|
|
)}
|
|
<div className="flex flex-col gap-2 px-3 py-3">
|
|
<h5 className="line-clamp-1 font-medium leading-none text-zinc-200">
|
|
{data.title}
|
|
</h5>
|
|
{data.description && (
|
|
<p className="line-clamp-3 break-all text-sm text-zinc-400">
|
|
{data.description}
|
|
</p>
|
|
)}
|
|
<span className="mt-2.5 text-sm leading-none text-zinc-500">
|
|
{domain.hostname}
|
|
</span>
|
|
</div>
|
|
</>
|
|
)}
|
|
</a>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|