feat: add reply form
This commit is contained in:
@@ -228,31 +228,25 @@ export class Ark {
|
||||
return [...events];
|
||||
}
|
||||
|
||||
public getCleanEventId(id: string) {
|
||||
let eventId: string = id.replace("nostr:", "").split("'")[0].split(".")[0];
|
||||
|
||||
if (
|
||||
eventId.startsWith("nevent1") ||
|
||||
eventId.startsWith("note1") ||
|
||||
eventId.startsWith("naddr1")
|
||||
) {
|
||||
const decode = nip19.decode(eventId);
|
||||
if (decode.type === "nevent") eventId = decode.data.id;
|
||||
if (decode.type === "note") eventId = decode.data;
|
||||
}
|
||||
|
||||
return eventId;
|
||||
}
|
||||
|
||||
public async getEventById(id: string) {
|
||||
try {
|
||||
let eventId: string = id
|
||||
.replace("nostr:", "")
|
||||
.split("'")[0]
|
||||
.split(".")[0];
|
||||
|
||||
if (
|
||||
eventId.startsWith("nevent1") ||
|
||||
eventId.startsWith("note1") ||
|
||||
eventId.startsWith("naddr1")
|
||||
) {
|
||||
const decode = nip19.decode(eventId);
|
||||
|
||||
if (decode.type === "nevent") eventId = decode.data.id;
|
||||
if (decode.type === "note") eventId = decode.data;
|
||||
if (decode.type === "naddr") {
|
||||
return await this.ndk.fetchEvent({
|
||||
kinds: [decode.data.kind],
|
||||
"#d": [decode.data.identifier],
|
||||
authors: [decode.data.pubkey],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const eventId = this.getCleanEventId(id);
|
||||
return await this.ndk.fetchEvent(eventId);
|
||||
} catch {
|
||||
throw new Error("event not found");
|
||||
@@ -304,19 +298,19 @@ export class Ark {
|
||||
};
|
||||
}
|
||||
|
||||
public async getThreads({ id }: { id: string }) {
|
||||
public async getThreads(id: string) {
|
||||
const eventId = this.getCleanEventId(id);
|
||||
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(this.ndk));
|
||||
const relayUrls = [...this.ndk.pool.relays.values()].map(
|
||||
(item) => item.url,
|
||||
);
|
||||
|
||||
try {
|
||||
const relayUrls = [...this.ndk.pool.relays.values()].map(
|
||||
(item) => item.url,
|
||||
);
|
||||
|
||||
const rawEvents = (await fetcher.fetchAllEvents(
|
||||
relayUrls,
|
||||
{
|
||||
kinds: [NDKKind.Text],
|
||||
"#e": [id],
|
||||
"#e": [eventId],
|
||||
},
|
||||
{ since: 0 },
|
||||
{ sort: true },
|
||||
|
||||
@@ -48,12 +48,12 @@ export function ImagePreview({ url }: { url: string }) {
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => downloadImage(e)}
|
||||
className="absolute z-10 items-center justify-center hidden w-10 h-10 bg-blue-500 rounded-lg right-2 top-2 group-hover:inline-flex hover:bg-blue-600"
|
||||
className="absolute z-10 items-center justify-center hidden size-8 bg-white/10 text-white backdrop-blur-xl rounded-lg right-2 top-2 group-hover:inline-flex hover:bg-blue-500"
|
||||
>
|
||||
{downloaded ? (
|
||||
<CheckCircleIcon className="w-5 h-5 text-white" />
|
||||
<CheckCircleIcon className="size-4" />
|
||||
) : (
|
||||
<DownloadIcon className="w-5 h-5 text-white" />
|
||||
<DownloadIcon className="size-4" />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -6,15 +6,13 @@ export function ChildReply({
|
||||
}: { event: NDKEvent; rootEventId?: string }) {
|
||||
return (
|
||||
<Note.Provider event={event}>
|
||||
<Note.Root className="gap-2 pl-4 mb-5">
|
||||
<div className="flex items-center justify-between px-3 h-14">
|
||||
<Note.User className="flex-1 pr-1" />
|
||||
<Note.Root className="pl-6">
|
||||
<div className="flex items-center justify-between h-14">
|
||||
<Note.User className="flex-1" />
|
||||
<Note.Menu />
|
||||
</div>
|
||||
<Note.Content className="min-w-0" />
|
||||
<div className="flex items-center gap-10 -ml-1">
|
||||
<Note.Reply />
|
||||
<Note.Reaction />
|
||||
<Note.Content />
|
||||
<div className="flex items-center justify-end gap-10 mt-4">
|
||||
<Note.Repost />
|
||||
<Note.Zap />
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { NavArrowDownIcon } from "@lume/icons";
|
||||
import { NDKEventWithReplies } from "@lume/types";
|
||||
import { cn } from "@lume/utils";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useState } from "react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { Note } from "..";
|
||||
import { ChildReply } from "./childReply";
|
||||
|
||||
@@ -16,35 +16,33 @@ export function Reply({
|
||||
return (
|
||||
<Collapsible.Root open={open} onOpenChange={setOpen}>
|
||||
<Note.Provider event={event}>
|
||||
<Note.Root>
|
||||
<div className="flex items-center justify-between px-3 h-14">
|
||||
<Note.Root className="pt-2">
|
||||
<div className="flex items-center justify-between h-14">
|
||||
<Note.User className="flex-1 pr-1" />
|
||||
<Note.Menu />
|
||||
</div>
|
||||
<Note.Content className="min-w-0 px-3" />
|
||||
<div className="flex items-center justify-between px-3 -ml-1 h-14">
|
||||
<Note.Content />
|
||||
<div className="flex items-center justify-between h-14">
|
||||
{event.replies?.length > 0 ? (
|
||||
<Collapsible.Trigger asChild>
|
||||
<div className="inline-flex items-center gap-1 ml-1 font-semibold text-blue-500 h-14">
|
||||
<div className="inline-flex items-center gap-1 font-semibold text-sm text-neutral-600 dark:text-neutral-400 h-14">
|
||||
<NavArrowDownIcon
|
||||
className={twMerge(
|
||||
"h-3 w-3",
|
||||
open ? "rotate-180 transform" : "",
|
||||
)}
|
||||
className={cn("size-5", open ? "rotate-180 transform" : "")}
|
||||
/>
|
||||
{`${event.replies?.length} ${
|
||||
event.replies?.length === 1 ? "reply" : "replies"
|
||||
}`}
|
||||
</div>
|
||||
</Collapsible.Trigger>
|
||||
) : null}
|
||||
) : (
|
||||
<div />
|
||||
)}
|
||||
<div className="inline-flex items-center gap-10">
|
||||
<Note.Reply />
|
||||
<Note.Repost />
|
||||
<Note.Zap />
|
||||
</div>
|
||||
</div>
|
||||
<div className={twMerge("px-3", open ? "pb-3" : "")}>
|
||||
<div className={cn("", open ? "pb-3" : "")}>
|
||||
{event.replies?.length > 0 ? (
|
||||
<Collapsible.Content>
|
||||
{event.replies?.map((childEvent) => (
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { RepostIcon } from "@lume/icons";
|
||||
import { cn } from "@lume/utils";
|
||||
import { NDKEvent, NostrEvent } from "@nostr-dev-kit/ndk";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Note } from "..";
|
||||
@@ -69,7 +70,12 @@ export function RepostNote({
|
||||
}
|
||||
|
||||
return (
|
||||
<Note.Root className={className}>
|
||||
<Note.Root
|
||||
className={cn(
|
||||
"flex flex-col rounded-xl bg-neutral-50 dark:bg-neutral-950",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<User.Provider pubkey={event.pubkey}>
|
||||
<User.Root className="flex gap-2 px-3 h-14">
|
||||
<div className="inline-flex shrink-0 w-10 items-center justify-center">
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { cn } from "@lume/utils";
|
||||
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
||||
import { Note } from "..";
|
||||
|
||||
@@ -7,7 +8,12 @@ export function TextNote({
|
||||
}: { event: NDKEvent; className?: string }) {
|
||||
return (
|
||||
<Note.Provider event={event}>
|
||||
<Note.Root className={className}>
|
||||
<Note.Root
|
||||
className={cn(
|
||||
"flex flex-col rounded-xl bg-neutral-50 dark:bg-neutral-950",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center justify-between px-3 h-14">
|
||||
<Note.User className="flex-1 pr-1" />
|
||||
<Note.Menu />
|
||||
|
||||
@@ -11,7 +11,7 @@ export function ThreadNote({ eventId }: { eventId: string }) {
|
||||
|
||||
return (
|
||||
<Note.Provider event={data}>
|
||||
<Note.Root>
|
||||
<Note.Root className="flex flex-col rounded-xl bg-neutral-50 dark:bg-neutral-950">
|
||||
<div className="flex items-center justify-between px-3 h-16">
|
||||
<User.Provider pubkey={data.pubkey}>
|
||||
<User.Root className="flex h-16 items-center gap-3 flex-1">
|
||||
@@ -29,11 +29,10 @@ export function ThreadNote({ eventId }: { eventId: string }) {
|
||||
<Note.Menu />
|
||||
</div>
|
||||
<Note.Thread className="mb-2" />
|
||||
<Note.Content className="min-w-0 px-3" isTranslatable />
|
||||
<Note.Content className="min-w-0 px-3" />
|
||||
<div className="flex items-center justify-between px-3 h-14">
|
||||
<Note.Pin />
|
||||
<div className="inline-flex items-center gap-10">
|
||||
<Note.Reply />
|
||||
<Note.Repost />
|
||||
<Note.Zap />
|
||||
</div>
|
||||
|
||||
@@ -10,10 +10,7 @@ export function NoteRoot({
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex h-min w-full flex-col overflow-hidden rounded-xl bg-neutral-50 dark:bg-neutral-950",
|
||||
className,
|
||||
)}
|
||||
className={cn("h-min w-full overflow-hidden", className)}
|
||||
contentEditable={false}
|
||||
>
|
||||
{children}
|
||||
|
||||
Reference in New Issue
Block a user