From 24f0c0f9cd96f755942a43c915d5838fc80c580a Mon Sep 17 00:00:00 2001 From: mroxso <24775431+mroxso@users.noreply.github.com> Date: Sat, 24 May 2025 21:19:28 +0200 Subject: [PATCH] feat: Add CardOptionsDropdown component for sharing and viewing raw (#118) * feat: Add CardOptionsDropdown component for sharing and viewing raw event data in NoteCard and KIND20Card * Update components/CardOptionsDropdown.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update components/CardOptionsDropdown.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: Import useMemo in CardOptionsDropdown for optimized rendering --------- Co-authored-by: highperfocused Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- components/CardOptionsDropdown.tsx | 148 +++++++++++++++++++++++++++++ components/KIND20Card.tsx | 12 +-- components/NoteCard.tsx | 14 +-- 3 files changed, 157 insertions(+), 17 deletions(-) create mode 100644 components/CardOptionsDropdown.tsx diff --git a/components/CardOptionsDropdown.tsx b/components/CardOptionsDropdown.tsx new file mode 100644 index 0000000..3b9a9e8 --- /dev/null +++ b/components/CardOptionsDropdown.tsx @@ -0,0 +1,148 @@ +import React, { useMemo } from 'react'; +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { + Drawer, + DrawerClose, + DrawerContent, + DrawerDescription, + DrawerFooter, + DrawerHeader, + DrawerTitle, + DrawerTrigger, +} from "@/components/ui/drawer"; +import { Textarea } from "./ui/textarea"; +import { DotsVerticalIcon, CodeIcon, Share1Icon } from "@radix-ui/react-icons"; +import { Input } from "./ui/input"; +import { useRef, useState } from 'react'; +import { useToast } from "./ui/use-toast"; +import { Event as NostrEvent, nip19 } from "nostr-tools"; + +interface CardOptionsDropdownProps { + event: NostrEvent; +} + +export default function CardOptionsDropdown({ event }: CardOptionsDropdownProps) { + const jsonEvent = useMemo(() => JSON.stringify(event, null, 2), [event]); + const inputRef = useRef(null); + const inputRefID = useRef(null); + const { toast } = useToast(); + const [dropdownOpen, setDropdownOpen] = useState(false); + const [shareDrawerOpen, setShareDrawerOpen] = useState(false); + const [rawDrawerOpen, setRawDrawerOpen] = useState(false); + + const handleCopyLink = async () => { + try { + await navigator.clipboard.writeText(window.location.href); + toast({ + description: 'URL copied to clipboard', + title: 'Copied' + }); + } catch (err) { + toast({ + description: 'Error copying URL to clipboard', + title: 'Error', + variant: 'destructive' + }); + } + }; + + const handleCopyNoteId = async () => { + try { + await navigator.clipboard.writeText(nip19.noteEncode(event.id)); + toast({ + description: 'Note ID copied to clipboard', + title: 'Copied' + }); + } catch (err) { + toast({ + description: 'Error copying Note ID to clipboard', + title: 'Error', + variant: 'destructive' + }); + } + }; + + return ( + <> + + + + + + {/* Share option */} + { + setDropdownOpen(false); + setTimeout(() => setShareDrawerOpen(true), 100); + }} + > + + Share + + + {/* View Raw option */} + { + setDropdownOpen(false); + setTimeout(() => setRawDrawerOpen(true), 100); + }} + > + + View Raw + + + + + {/* Share Drawer */} + + + + Share this Note + Share this Note with others. + +
+
+ + +
+
+ + +
+
+ + + + + +
+
+ + {/* Raw Event Drawer */} + + + + Raw Event + This shows the raw event data. + +
+