update thread

This commit is contained in:
Ren Amamiya
2023-06-27 11:42:12 +07:00
parent 2f553d8039
commit 6abff45678
25 changed files with 396 additions and 295 deletions

View File

@@ -87,19 +87,21 @@ export function ActiveAccount({ data }: { data: any }) {
};
}, []);
if (status === "loading") {
return <div className="w-9 h-9 rounded bg-zinc-800 animate-pulse" />;
}
return (
<button type="button" className="relative inline-block h-9 w-9">
{status === "loading" ? (
<div className="w-9 h-9 rounded bg-zinc-800 animate-pulse" />
) : (
<div className="inline-flex items-center gap-2">
<div className="relative inline-block h-9 w-9">
<Image
src={user.image}
fallback={DEFAULT_AVATAR}
alt={data.npub}
className="h-9 w-9 rounded object-cover"
/>
)}
<NetworkStatusIndicator />
</button>
<NetworkStatusIndicator />
</div>
</div>
);
}

View File

@@ -7,13 +7,12 @@ import { useState } from "react";
import { Link } from "react-router-dom";
export function MultiAccounts() {
const {
status,
data: activeAccount,
isFetching,
} = useQuery(["activeAccount"], async () => {
return await getActiveAccount();
});
const { status, data: activeAccount } = useQuery(
["activeAccount"],
async () => {
return await getActiveAccount();
},
);
const [open, setOpen] = useState(false);
@@ -25,7 +24,7 @@ export function MultiAccounts() {
<div className="flex flex-col gap-2 rounded-xl p-2 border-t border-zinc-800/50 bg-zinc-900/80 backdrop-blur-md">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
{status === "loading" || isFetching ? (
{status === "loading" ? (
<div className="group relative flex h-9 w-9 shrink animate-pulse items-center justify-center rounded-lg bg-zinc-900" />
) : (
<ActiveAccount data={activeAccount} />

View File

@@ -8,7 +8,7 @@ import { useEvent } from "@utils/hooks/useEvent";
import { memo } from "react";
export const MentionNote = memo(function MentionNote({ id }: { id: string }) {
const { status, data, isFetching } = useEvent(id);
const { status, data } = useEvent(id);
const kind1 = data?.kind === 1 ? data.content : null;
const kind1063 = data?.kind === 1063 ? data.tags : null;
@@ -39,7 +39,7 @@ export const MentionNote = memo(function MentionNote({ id }: { id: string }) {
onKeyDown={(e) => openThread(e, id)}
className="mt-3 rounded-lg bg-zinc-800 border-t border-zinc-700/50 px-3 py-3"
>
{isFetching || status === "loading" ? (
{status === "loading" ? (
<NoteSkeleton />
) : (
<>

View File

@@ -19,60 +19,57 @@ export function NoteMetadata({
currentBlock?: number;
}) {
const ndk = useContext(RelayContext);
const { status, data, isFetching } = useQuery(
["note-metadata", id],
async () => {
let replies = 0;
let reposts = 0;
let zap = 0;
const { status, data } = useQuery(["note-metadata", id], async () => {
let replies = 0;
let reposts = 0;
let zap = 0;
const filter: NDKFilter = {
"#e": [id],
kinds: [1, 6, 9735],
};
const filter: NDKFilter = {
"#e": [id],
kinds: [1, 6, 9735],
};
const events = await ndk.fetchEvents(filter);
events.forEach((event: NDKEvent) => {
switch (event.kind) {
case 1:
replies += 1;
createReplyNote(
id,
event.id,
event.pubkey,
event.kind,
event.tags,
event.content,
event.created_at,
const events = await ndk.fetchEvents(filter);
events.forEach((event: NDKEvent) => {
switch (event.kind) {
case 1:
replies += 1;
createReplyNote(
id,
event.id,
event.pubkey,
event.kind,
event.tags,
event.content,
event.created_at,
);
break;
case 6:
reposts += 1;
break;
case 9735: {
const bolt11 = event.tags.find((tag) => tag[0] === "bolt11")[1];
if (bolt11) {
const decoded = decode(bolt11);
const amount = decoded.sections.find(
(item) => item.name === "amount",
);
break;
case 6:
reposts += 1;
break;
case 9735: {
const bolt11 = event.tags.find((tag) => tag[0] === "bolt11")[1];
if (bolt11) {
const decoded = decode(bolt11);
const amount = decoded.sections.find(
(item) => item.name === "amount",
);
const sats = amount.value / 1000;
zap += sats;
}
break;
const sats = amount.value / 1000;
zap += sats;
}
default:
break;
break;
}
});
default:
break;
}
});
return { replies, reposts, zap };
},
);
return { replies, reposts, zap };
});
return (
<div className="inline-flex items-center w-full h-12 mt-2">
{status === "loading" || isFetching ? (
{status === "loading" ? (
<>
<div className="w-20 group inline-flex items-center gap-1.5">
<ReplyIcon

View File

@@ -9,12 +9,12 @@ export function NoteParent({
id,
currentBlock,
}: { id: string; currentBlock: number }) {
const { status, data, isFetching } = useEvent(id);
const { status, data } = useEvent(id);
return (
<div className="relative overflow-hidden flex flex-col pb-6">
<div className="absolute left-[18px] top-0 h-full w-0.5 bg-gradient-to-t from-zinc-800 to-zinc-600" />
{isFetching || status === "loading" ? (
{status === "loading" ? (
<NoteSkeleton />
) : (
<>

View File

@@ -14,7 +14,7 @@ export function NoteReplyForm({ id }: { id: string }) {
const [value, setValue] = useState("");
const submitEvent = () => {
const submit = () => {
const tags = [["e", id]];
// publish event
@@ -28,7 +28,7 @@ export function NoteReplyForm({ id }: { id: string }) {
<div className="flex flex-col">
<div className="relative w-full flex-1 overflow-hidden">
<textarea
name="content"
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Reply to this thread..."
className="relative h-20 w-full resize-none rounded-md px-5 py-3 text-base bg-transparent !outline-none placeholder:text-zinc-400 dark:text-zinc-100 dark:placeholder:text-zinc-500"
@@ -62,7 +62,7 @@ export function NoteReplyForm({ id }: { id: string }) {
</div>
<div className="flex items-center gap-2">
<Button
onClick={() => submitEvent()}
onClick={() => submit()}
disabled={value.length === 0 ? true : false}
preset="publish"
>

View File

@@ -12,7 +12,7 @@ export function Reply({ data }: { data: any }) {
<User pubkey={data.pubkey} time={data.created_at} />
<div className="-mt-[20px] pl-[50px]">
<Kind1 content={content} />
<NoteMetadata id={data.id} eventPubkey={data.pubkey} />
<NoteMetadata id={data.event_id} eventPubkey={data.pubkey} />
</div>
</div>
</div>

View File

@@ -1,11 +1,10 @@
import { getReplies } from "@libs/storage";
import { NDKEvent } from "@nostr-dev-kit/ndk";
import { EmptyIcon } from "@shared/icons";
import { Reply } from "@shared/notes/replies/item";
import { useQuery } from "@tanstack/react-query";
export function RepliesList({ parent_id }: { parent_id: string }) {
const { data } = useQuery(["replies", parent_id], async () => {
const { status, data } = useQuery(["replies", parent_id], async () => {
return await getReplies(parent_id);
});
@@ -15,7 +14,7 @@ export function RepliesList({ parent_id }: { parent_id: string }) {
<h5 className="text-lg font-semibold text-zinc-300">Replies</h5>
</div>
<div className="flex flex-col">
{!data ? (
{status === "loading" ? (
<div className="flex gap-2 px-3 py-4">
<div className="relative h-9 w-9 shrink animate-pulse rounded-md bg-zinc-800" />
<div className="flex w-full flex-1 flex-col justify-center gap-1">

View File

@@ -12,12 +12,12 @@ export function Repost({
currentBlock,
}: { event: LumeEvent; currentBlock?: number }) {
const repostID = getRepostID(event.tags);
const { status, data, isFetching } = useEvent(repostID);
const { status, data } = useEvent(repostID);
return (
<div className="relative flex flex-col mt-12">
<div className="absolute left-[18px] -top-10 h-[50px] w-0.5 bg-gradient-to-t from-zinc-800 to-zinc-600" />
{isFetching || status === "loading" ? (
{status === "loading" ? (
<NoteSkeleton />
) : (
<>