update threads (kind 30023) page

This commit is contained in:
Ren Amamiya 2023-05-16 09:56:24 +07:00
parent 180e31d1bd
commit 7e8e5a931b
4 changed files with 77 additions and 13 deletions

View File

@ -1,8 +1,15 @@
import { useProfile } from "@utils/hooks/useProfile";
import { shortenKey } from "@utils/shortenKey";
const hexRegex = /[0-9A-Fa-f]{6}/g;
export function MentionUser(props: { children: any[] }) {
const pubkey = props.children[0];
const pubkey = props.children[0].match(hexRegex) ? props.children[0] : null;
if (!pubkey) {
return null;
}
const { user } = useProfile(pubkey);
return (

View File

@ -1,11 +1,40 @@
import { Image } from "@shared/image";
import { DEFAULT_AVATAR, IMGPROXY_URL } from "@stores/constants";
import { useProfile } from "@utils/hooks/useProfile";
import { shortenKey } from "@utils/shortenKey";
import dayjs from "dayjs";
export function ThreadAuthor({
pubkey,
time,
}: { pubkey: string; time: number }) {
const { user } = useProfile(pubkey);
return (
<div>
<p>{pubkey}</p>
<span>{time}</span>
<div className="relative flex items-center gap-2.5">
<div className="h-9 w-9 shrink-0 overflow-hidden rounded-md bg-zinc-900">
<Image
src={`${IMGPROXY_URL}/rs:fit:100:100/plain/${
user?.picture ? user.picture : DEFAULT_AVATAR
}`}
alt={pubkey}
className="h-9 w-9 object-cover"
/>
</div>
<div className="flex w-full flex-1 items-start justify-between">
<div className="flex flex-col gap-0.5">
<h5 className="text-sm font-semibold leading-none">
{user?.display_name || user?.name || (
<div className="h-3 w-20 animate-pulse rounded-sm bg-zinc-700" />
)}
</h5>
<div className="flex items-baseline gap-1.5 text-sm leading-none text-zinc-500">
<span>{user?.nip05 || shortenKey(pubkey)}</span>
<span></span>
<span>{dayjs().to(dayjs.unix(time), true)}</span>
</div>
</div>
</div>
</div>
);
}

View File

@ -1,18 +1,37 @@
import { ThreadAuthor } from "@app/threads/components/author";
import { Image } from "@shared/image";
export function ThreadBase({ event }: { event: any }) {
const metadata = JSON.parse(event.metadata);
const title = metadata.find((i: any) => i[0] === "title")[1];
const summary = metadata.find((i: any) => i[0] === "summary")[1] || "";
const metadata = JSON.parse(event.tags);
const title = metadata.find((i: any) => i[0] === "title")?.[1];
const summary = metadata.find((i: any) => i[0] === "summary")?.[1];
const image = metadata.find((i: any) => i[0] === "image")?.[1];
if (!title) {
return null;
}
return (
<div className="h-min w-full px-3 py-1.5">
<div className="rounded-md border border-zinc-800 bg-zinc-900 shadow-input shadow-black/20">
<div className="px-3 py-3">
<h3>{title}</h3>
<p>{summary}</p>
<div className="flex flex-row gap-2">
<div className="flex-1">
<h3 className="text-zinc-100 text-xl font-semibold">{title}</h3>
<div className="mt-2 prose prose-zinc max-w-none select-text break-words dark:prose-invert prose-p:text-[15px] prose-p:leading-tight prose-a:text-[15px] prose-a:font-normal prose-a:leading-tight prose-a:text-fuchsia-500 prose-a:no-underline hover:prose-a:text-fuchsia-600 hover:prose-a:underline prose-ol:mb-1 prose-ul:mb-1 prose-li:text-[15px] prose-li:leading-tight">
<p>{summary}</p>
</div>
</div>
<div className="shrink-0 w-32 h-32">
<Image
src={image}
alt={title}
className="w-32 h-32 rounded-md object-cover"
/>
</div>
</div>
</div>
<div className="inline-flex w-full justify-between items-center px-3 h-10">
<div className="inline-flex border-t border-zinc-800 w-full justify-between items-center px-3 h-16">
<ThreadAuthor pubkey={event.pubkey} time={event.created_at} />
</div>
</div>

View File

@ -8,6 +8,15 @@ import { useEffect, useRef } from "react";
const ITEM_PER_PAGE = 10;
const TIME = Math.floor(Date.now() / 1000);
function isJSON(str: string) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
export function Page() {
const {
status,
@ -56,7 +65,7 @@ export function Page() {
return (
<div
ref={parentRef}
className="scrollbar-hide flex h-full flex-col justify-between gap-1.5 overflow-y-auto"
className="scrollbar-hide h-full overflow-y-auto"
style={{ contain: "strict" }}
>
{status === "loading" ? (
@ -69,7 +78,7 @@ export function Page() {
<div>{error.message}</div>
) : (
<div
className="relative w-full"
className="relative w-full mt-2"
style={{
height: `${rowVirtualizer.getTotalSize()}px`,
}}
@ -84,7 +93,7 @@ export function Page() {
>
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
const note = allRows[virtualRow.index];
if (note) {
if (note && isJSON(note.tags)) {
return (
<div
key={virtualRow.index}