refactor(ark): update note component
This commit is contained in:
@@ -9,7 +9,6 @@ import { NoteMediaContent } from "./kinds/media";
|
||||
import { NoteTextContent } from "./kinds/text";
|
||||
import { NoteMenu } from "./menu";
|
||||
import { NoteProvider } from "./provider";
|
||||
import { NoteReplyList } from "./reply";
|
||||
import { NoteRoot } from "./root";
|
||||
import { NoteThread } from "./thread";
|
||||
import { NoteUser } from "./user";
|
||||
@@ -29,14 +28,14 @@ export const Note = {
|
||||
TextContent: NoteTextContent,
|
||||
MediaContent: NoteMediaContent,
|
||||
ArticleContent: NoteArticleContent,
|
||||
ReplyList: NoteReplyList,
|
||||
};
|
||||
|
||||
export * from "./provider";
|
||||
export * from "./builds/text";
|
||||
export * from "./builds/repost";
|
||||
export * from "./builds/skeleton";
|
||||
export * from "./builds/thread";
|
||||
export * from "./primitives/text";
|
||||
export * from "./primitives/repost";
|
||||
export * from "./primitives/skeleton";
|
||||
export * from "./primitives/thread";
|
||||
export * from "./primitives/reply";
|
||||
export * from "./preview/image";
|
||||
export * from "./preview/link";
|
||||
export * from "./preview/video";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { cn } from "@lume/utils";
|
||||
import { useRichContent } from "../../../hooks/useRichContent";
|
||||
|
||||
export function NoteTextContent({
|
||||
@@ -12,7 +12,7 @@ export function NoteTextContent({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={twMerge(
|
||||
className={cn(
|
||||
"break-p select-text whitespace-pre-line text-balance leading-normal",
|
||||
className,
|
||||
)}
|
||||
|
||||
@@ -21,6 +21,10 @@ export function NoteMenu() {
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
const copyRaw = async () => {
|
||||
await writeText(JSON.stringify(await event.toNostrEvent()));
|
||||
};
|
||||
|
||||
const copyLink = async () => {
|
||||
await writeText(
|
||||
`https://njump.me/${nip19.neventEncode({
|
||||
@@ -42,12 +46,12 @@ export function NoteMenu() {
|
||||
</button>
|
||||
</DropdownMenu.Trigger>
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content className="flex w-[200px] flex-col overflow-hidden rounded-xl border border-neutral-200 bg-neutral-950 focus:outline-none dark:border-neutral-900">
|
||||
<DropdownMenu.Content className="flex w-[200px] p-2 flex-col overflow-hidden rounded-xl border border-neutral-200 bg-neutral-950 focus:outline-none dark:border-neutral-900">
|
||||
<DropdownMenu.Item asChild>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => copyLink()}
|
||||
className="inline-flex h-10 items-center px-4 text-sm text-white hover:bg-neutral-900 focus:outline-none"
|
||||
className="inline-flex h-10 items-center px-4 text-sm text-white hover:bg-neutral-900 rounded-lg focus:outline-none"
|
||||
>
|
||||
Copy shareable link
|
||||
</button>
|
||||
@@ -56,15 +60,24 @@ export function NoteMenu() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => copyID()}
|
||||
className="inline-flex h-10 items-center px-4 text-sm text-white hover:bg-neutral-900 focus:outline-none"
|
||||
className="inline-flex h-10 items-center px-4 text-sm text-white hover:bg-neutral-900 rounded-lg focus:outline-none"
|
||||
>
|
||||
Copy note ID
|
||||
</button>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item asChild>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => copyRaw()}
|
||||
className="inline-flex h-10 items-center px-4 text-sm text-white hover:bg-neutral-900 rounded-lg focus:outline-none"
|
||||
>
|
||||
Copy raw event
|
||||
</button>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item asChild>
|
||||
<Link
|
||||
to={`/users/${event.pubkey}`}
|
||||
className="inline-flex h-10 items-center px-4 text-sm text-white hover:bg-neutral-900 focus:outline-none"
|
||||
className="inline-flex h-10 items-center px-4 text-sm text-white hover:bg-neutral-900 rounded-lg focus:outline-none"
|
||||
>
|
||||
View profile
|
||||
</Link>
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
import { LoaderIcon } from "@lume/icons";
|
||||
import { NDKEventWithReplies } from "@lume/types";
|
||||
import { NDKSubscription } from "@nostr-dev-kit/ndk";
|
||||
import { useEffect, useState } from "react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { useArk } from "../../provider";
|
||||
import { Reply } from "./builds/reply";
|
||||
|
||||
export function NoteReplyList({
|
||||
eventId,
|
||||
title,
|
||||
className,
|
||||
}: { eventId: string; title?: string; className?: string }) {
|
||||
const ark = useArk();
|
||||
const [data, setData] = useState<null | NDKEventWithReplies[]>(null);
|
||||
|
||||
useEffect(() => {
|
||||
let sub: NDKSubscription;
|
||||
let isCancelled = false;
|
||||
|
||||
async function fetchRepliesAndSub() {
|
||||
const events = await ark.getThreads({ id: eventId });
|
||||
if (!isCancelled) {
|
||||
setData(events);
|
||||
}
|
||||
// subscribe for new replies
|
||||
sub = ark.subscribe({
|
||||
filter: {
|
||||
"#e": [eventId],
|
||||
since: Math.floor(Date.now() / 1000),
|
||||
},
|
||||
closeOnEose: false,
|
||||
cb: (event: NDKEventWithReplies) => setData((prev) => [event, ...prev]),
|
||||
});
|
||||
}
|
||||
|
||||
fetchRepliesAndSub();
|
||||
|
||||
return () => {
|
||||
isCancelled = true;
|
||||
if (sub) sub.stop();
|
||||
};
|
||||
}, [eventId]);
|
||||
|
||||
return (
|
||||
<div className={twMerge("flex flex-col gap-5", className)}>
|
||||
<h3 className="font-semibold">{title}</h3>
|
||||
{!data ? (
|
||||
<div className="flex h-16 items-center justify-center rounded-xl bg-neutral-50 p-3 dark:bg-neutral-950">
|
||||
<LoaderIcon className="h-5 w-5 animate-spin" />
|
||||
</div>
|
||||
) : data.length === 0 ? (
|
||||
<div className="flex w-full items-center justify-center bg-neutral-50 dark:bg-neutral-950 rounded-lg">
|
||||
<div className="flex flex-col items-center justify-center gap-2 py-6">
|
||||
<h3 className="text-3xl">👋</h3>
|
||||
<p className="leading-none text-neutral-600 dark:text-neutral-400">
|
||||
Be the first to Reply!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
data.map((event) => (
|
||||
<Reply key={event.id} event={event} rootEvent={eventId} />
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user