From d81bb130385114389728f849d0ab8cccf62b90d1 Mon Sep 17 00:00:00 2001 From: xXJsonDeruloXx Date: Fri, 20 Mar 2026 17:32:52 -0400 Subject: Add Steam UI for prefix-managed integration --- src/components/SmartClipboardButton.tsx | 123 ++++++++------------------------ 1 file changed, 30 insertions(+), 93 deletions(-) (limited to 'src/components/SmartClipboardButton.tsx') diff --git a/src/components/SmartClipboardButton.tsx b/src/components/SmartClipboardButton.tsx index d88a58a..8cc52b1 100644 --- a/src/components/SmartClipboardButton.tsx +++ b/src/components/SmartClipboardButton.tsx @@ -1,119 +1,68 @@ -import { useState, useEffect } from "react"; -import { PanelSectionRow, ButtonItem, ConfirmModal, showModal } from "@decky/ui"; -import { FaClipboard, FaCheck } from "react-icons/fa"; +import { useEffect, useState } from "react"; +import { ButtonItem, PanelSectionRow } from "@decky/ui"; import { toaster } from "@decky/api"; +import { FaCheck, FaClipboard } from "react-icons/fa"; interface SmartClipboardButtonProps { command?: string; buttonText?: string; } -export function SmartClipboardButton({ - command = "~/fgmod/fgmod %command%", - buttonText = "Copy Launch Command" +export function SmartClipboardButton({ + command = 'OPTISCALER_PROXY=winmm ~/fgmod/fgmod %command%', + buttonText = 'Copy Launch Command', }: SmartClipboardButtonProps) { const [isLoading, setIsLoading] = useState(false); const [showSuccess, setShowSuccess] = useState(false); - // Reset success state after 3 seconds useEffect(() => { - if (showSuccess) { - const timer = setTimeout(() => { - setShowSuccess(false); - }, 3000); - return () => clearTimeout(timer); - } - return undefined; + if (!showSuccess) return undefined; + const timer = setTimeout(() => setShowSuccess(false), 3000); + return () => clearTimeout(timer); }, [showSuccess]); - const copyToClipboard = async () => { - if (isLoading || showSuccess) return; - - const isPatchCommand = command.includes("fgmod %command%") && !command.includes("uninstaller"); - - if (isPatchCommand) { - showModal( - { - await performCopy(); - }} - /> - ); - return; - } - - // For non-patch commands, copy directly - await performCopy(); - }; - const performCopy = async () => { if (isLoading || showSuccess) return; - + setIsLoading(true); try { - const text = command; - - // Use the proven input simulation method - const tempInput = document.createElement('input'); - tempInput.value = text; - tempInput.style.position = 'absolute'; - tempInput.style.left = '-9999px'; + const tempInput = document.createElement("input"); + tempInput.value = command; + tempInput.style.position = "absolute"; + tempInput.style.left = "-9999px"; document.body.appendChild(tempInput); - - // Focus and select the text tempInput.focus(); tempInput.select(); - - // Try copying using execCommand first (most reliable in gaming mode) + let copySuccess = false; try { - if (document.execCommand('copy')) { + if (document.execCommand("copy")) { copySuccess = true; } - } catch (e) { - // If execCommand fails, try navigator.clipboard as fallback + } catch (execError) { try { - await navigator.clipboard.writeText(text); + await navigator.clipboard.writeText(command); copySuccess = true; } catch (clipboardError) { - console.error('Both copy methods failed:', e, clipboardError); + console.error("Clipboard copy failed", execError, clipboardError); } } - - // Clean up + document.body.removeChild(tempInput); - - if (copySuccess) { - // Show success feedback in the button instead of toast - setShowSuccess(true); - // Verify the copy worked by reading back - try { - const readBack = await navigator.clipboard.readText(); - if (readBack !== text) { - // Copy worked but verification failed - still show success - console.log('Copy verification failed but copy likely worked'); - } - } catch (e) { - // Verification failed but copy likely worked - console.log('Copy verification unavailable but copy likely worked'); - } - } else { + + if (!copySuccess) { toaster.toast({ title: "Copy Failed", - body: "Unable to copy to clipboard" + body: "Unable to copy to clipboard", }); + return; } + setShowSuccess(true); } catch (error) { toaster.toast({ title: "Copy Failed", - body: `Error: ${String(error)}` + body: `Error: ${String(error)}`, }); } finally { setIsLoading(false); @@ -122,28 +71,16 @@ export function SmartClipboardButton({ return ( - +
{showSuccess ? ( - + ) : isLoading ? ( - + ) : ( )} -
+
{showSuccess ? "Copied to clipboard" : isLoading ? "Copying..." : buttonText}
-- cgit v1.2.3