import { useParams } from "react-router-dom"; import { useNostr } from "@nostrify/react"; import { useQuery } from "@tanstack/react-query"; import { nip19 } from "nostr-tools"; import { VoiceMessagePost } from "@/components/VoiceMessagePost"; import { Card } from "@/components/ui/card"; import { NostrEvent } from "@nostrify/nostrify"; interface ThreadedNostrEvent extends NostrEvent { replies: ThreadedNostrEvent[]; } export function VoiceMessagePage() { const { nevent } = useParams<{ nevent: string }>(); const { nostr } = useNostr(); const decoded = nevent ? nip19.decode(nevent) : null; const eventId = decoded?.type === "nevent" ? decoded.data.id : null; const { data: message, isLoading } = useQuery({ queryKey: ["voiceMessage", eventId], queryFn: async () => { if (!eventId) return null; const signal = AbortSignal.timeout(5000); const events = await nostr.query( [ { kinds: [1222], ids: [eventId], }, ], { signal } ); return events[0] ? { ...events[0], replies: [] } : null; }, enabled: !!eventId, }); // Fetch replies to this message const { data: replies, isLoading: isLoadingReplies } = useQuery({ queryKey: ["voiceMessageReplies", eventId], queryFn: async () => { if (!eventId) return []; const signal = AbortSignal.timeout(5000); const events = await nostr.query( [ { kinds: [1222], // Find replies where the 'e' tag references this eventId and is a reply "#e": [eventId], limit: 100, }, ], { signal } ); // Only include those with a tag type 'reply' const filteredReplies = events .filter((ev) => ev.tags.some( (tag) => tag[0] === "e" && tag[1] === eventId && tag[3] === "reply" ) ) .sort((a, b) => a.created_at - b.created_at) .map((ev) => ({ ...ev, replies: [] })); if (filteredReplies) { console.log( "VoiceMessagePage: replies.length =", filteredReplies.length, filteredReplies ); } return filteredReplies; }, enabled: !!eventId, }); // Check if the current message is a reply and get the root ID const rootTag = message?.tags.find( (tag) => tag[0] === "e" && tag[3] === "root" ); const rootId = rootTag ? rootTag[1] : null; // Fetch the root message if needed const { data: rootMessage } = useQuery({ queryKey: ["voiceMessageRoot", rootId], queryFn: async () => { if (!rootId) return null; const signal = AbortSignal.timeout(5000); const events = await nostr.query( [ { kinds: [1222], ids: [rootId], }, ], { signal } ); return events[0] ? { ...events[0], replies: [] } : null; }, enabled: !!rootId, }); if (!eventId) { return (