import { useState, useEffect } from "react"; import { PanelSectionRow } from "@decky/ui"; import { FaClipboard, FaEye } from "react-icons/fa"; export function ClipboardDisplay() { const [clipboardContent, setClipboardContent] = useState(""); const [isReading, setIsReading] = useState(false); const readClipboard = async () => { if (isReading) return; // Prevent concurrent reads setIsReading(true); try { console.log("ClipboardDisplay: Attempting to read clipboard..."); if (!navigator.clipboard) { console.log("ClipboardDisplay: navigator.clipboard not available"); setClipboardContent("Clipboard API not available"); return; } if (!navigator.clipboard.readText) { console.log("ClipboardDisplay: navigator.clipboard.readText not available"); setClipboardContent("Clipboard read not supported"); return; } console.log("ClipboardDisplay: Calling navigator.clipboard.readText()..."); const content = await navigator.clipboard.readText(); console.log("ClipboardDisplay: Successfully read clipboard:", content.length, "characters"); setClipboardContent(content); } catch (error) { // This is expected if user hasn't granted clipboard permissions // or if we're in a context where reading isn't allowed console.log("ClipboardDisplay: Error reading clipboard:", error); console.log("ClipboardDisplay: Error name:", (error as Error).name); console.log("ClipboardDisplay: Error message:", (error as Error).message); // More specific error messages based on error type if (error instanceof DOMException) { switch (error.name) { case 'NotAllowedError': setClipboardContent("Clipboard access denied - check permissions"); break; case 'NotFoundError': setClipboardContent("No clipboard data found"); break; case 'SecurityError': setClipboardContent("Clipboard access blocked by security policy"); break; default: setClipboardContent(`Clipboard error: ${error.name}`); } } else { setClipboardContent("Unable to read clipboard"); } } finally { setIsReading(false); } }; // Read clipboard on mount and then every 3 seconds useEffect(() => { readClipboard(); const interval = setInterval(() => { readClipboard(); }, 3000); return () => clearInterval(interval); }, []); const truncateText = (text: string, maxLength: number = 60) => { if (text.length <= maxLength) return text; return text.substring(0, maxLength) + "..."; }; const displayText = truncateText(clipboardContent); return (
Current Clipboard
{isReading && ( )}
{displayText || "Reading clipboard..."}
); }