diff --git a/src/components/WindowToolbar.tsx b/src/components/WindowToolbar.tsx index aee30ac..a20d832 100644 --- a/src/components/WindowToolbar.tsx +++ b/src/components/WindowToolbar.tsx @@ -1,4 +1,11 @@ -import { X, Pencil, MoreVertical, WandSparkles } from "lucide-react"; +import { + X, + Pencil, + MoreVertical, + WandSparkles, + Copy, + CopyCheck, +} from "lucide-react"; import { useSetAtom } from "jotai"; import { useState } from "react"; import { WindowInstance } from "@/types/app"; @@ -10,9 +17,12 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { Button } from "@/components/ui/button"; import { SpellDialog } from "@/components/nostr/SpellDialog"; import { reconstructCommand as reconstructReqCommand } from "@/lib/spell-conversion"; import { toast } from "sonner"; +import { useCopy } from "@/hooks/useCopy"; +import { useNip } from "@/hooks/useNip"; interface WindowToolbarProps { window?: WindowInstance; @@ -58,6 +68,22 @@ export function WindowToolbar({ setShowSpellDialog(true); }; + // Copy functionality for NIPs + const { copy, copied } = useCopy(); + const isNipWindow = window?.appId === "nip"; + + // Fetch NIP content for regular NIPs + const { content: nipContent } = useNip( + isNipWindow && window?.props?.number ? window.props.number : "", + ); + + const handleCopyNip = () => { + if (!window || !nipContent) return; + + copy(nipContent); + toast.success("NIP markdown copied to clipboard"); + }; + // Check if this is a REQ window for spell creation const isReqWindow = window?.appId === "req"; @@ -78,27 +104,46 @@ export function WindowToolbar({ <> {window && ( <> - {/* Edit button with keyboard shortcut hint */} - - + + + {/* Copy button for NIPs */} + {isNipWindow && ( + + {copied ? : } + + )} {/* More actions menu - only for REQ windows for now */} {isReqWindow && ( - - + @@ -124,14 +169,16 @@ export function WindowToolbar({ > )} {onClose && ( - - + )} > ); diff --git a/src/components/nostr/kinds/CommunityNIPDetailRenderer.tsx b/src/components/nostr/kinds/CommunityNIPDetailRenderer.tsx index 1a7c736..036ce81 100644 --- a/src/components/nostr/kinds/CommunityNIPDetailRenderer.tsx +++ b/src/components/nostr/kinds/CommunityNIPDetailRenderer.tsx @@ -1,7 +1,11 @@ import { useMemo } from "react"; +import { Copy, CopyCheck } from "lucide-react"; import { getTagValue } from "applesauce-core/helpers"; import { UserName } from "../UserName"; import { MarkdownContent } from "../MarkdownContent"; +import { Button } from "@/components/ui/button"; +import { useCopy } from "@/hooks/useCopy"; +import { toast } from "sonner"; import type { NostrEvent } from "@/types/nostr"; /** @@ -29,12 +33,30 @@ export function CommunityNIPDetailRenderer({ event }: { event: NostrEvent }) { }, ); + // Copy functionality + const { copy, copied } = useCopy(); + const handleCopy = () => { + copy(event.content); + toast.success("Community NIP markdown copied to clipboard"); + }; + return ( {/* NIP Header */} - {/* Title */} - {title} + {/* Title with Copy Button */} + + {title} + + {copied ? : } + + {/* Metadata */}