summaryrefslogtreecommitdiff
path: root/src/components/SmartClipboardButton.tsx
diff options
context:
space:
mode:
authorKurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>2025-07-28 07:21:34 -0700
committerGitHub <noreply@github.com>2025-07-28 10:21:34 -0400
commit56eac1ac74e9f32bbf2541929e80b79cdb6cbcb1 (patch)
treece3e213466aeba1c538679e0fb5e266a4141f953 /src/components/SmartClipboardButton.tsx
parent2461cb5d9c2ae31afb33bfd3c3c9a8faa9a7603c (diff)
downloadDecky-Framegen-56eac1ac74e9f32bbf2541929e80b79cdb6cbcb1.tar.gz
Decky-Framegen-56eac1ac74e9f32bbf2541929e80b79cdb6cbcb1.zip
refined copy to clipboard ui feedback (#122)
* copy feedback * add opti logo and update wording * branding updates * hide check mark when installed
Diffstat (limited to 'src/components/SmartClipboardButton.tsx')
-rw-r--r--src/components/SmartClipboardButton.tsx62
1 files changed, 34 insertions, 28 deletions
diff --git a/src/components/SmartClipboardButton.tsx b/src/components/SmartClipboardButton.tsx
index 7d250f5..095da15 100644
--- a/src/components/SmartClipboardButton.tsx
+++ b/src/components/SmartClipboardButton.tsx
@@ -1,31 +1,37 @@
-import { useState } from "react";
+import { useState, useEffect } from "react";
import { PanelSectionRow, ButtonItem } from "@decky/ui";
-import { FaClipboard } from "react-icons/fa";
+import { FaClipboard, FaCheck } from "react-icons/fa";
import { toaster } from "@decky/api";
interface SmartClipboardButtonProps {
command?: string;
buttonText?: string;
- successMessage?: string;
}
export function SmartClipboardButton({
command = "~/fgmod/fgmod %command%",
- buttonText = "Copy Launch Command",
- successMessage = "Launch option ready to paste"
+ buttonText = "Copy Launch Command"
}: SmartClipboardButtonProps) {
const [isLoading, setIsLoading] = useState(false);
+ const [showSuccess, setShowSuccess] = useState(false);
- const getLaunchOptionText = (): string => {
- return command;
- };
+ // Reset success state after 3 seconds
+ useEffect(() => {
+ if (showSuccess) {
+ const timer = setTimeout(() => {
+ setShowSuccess(false);
+ }, 3000);
+ return () => clearTimeout(timer);
+ }
+ return undefined;
+ }, [showSuccess]);
const copyToClipboard = async () => {
- if (isLoading) return;
+ if (isLoading || showSuccess) return;
setIsLoading(true);
try {
- const text = getLaunchOptionText();
+ const text = command;
// Use the proven input simulation method
const tempInput = document.createElement('input');
@@ -58,27 +64,18 @@ export function SmartClipboardButton({
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) {
- toaster.toast({
- title: "Copied to Clipboard!",
- body: successMessage
- });
- } else {
- // Copy worked but verification failed - still consider it success
- toaster.toast({
- title: "Copied to Clipboard!",
- body: "Launch option copied (verification unavailable)"
- });
+ 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
- toaster.toast({
- title: "Copied to Clipboard!",
- body: "Launch option copied successfully"
- });
+ console.log('Copy verification unavailable but copy likely worked');
}
} else {
toaster.toast({
@@ -102,10 +99,14 @@ export function SmartClipboardButton({
<ButtonItem
layout="below"
onClick={copyToClipboard}
- disabled={isLoading}
+ disabled={isLoading || showSuccess}
>
<div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
- {isLoading ? (
+ {showSuccess ? (
+ <FaCheck style={{
+ color: "#4CAF50" // Green color for success
+ }} />
+ ) : isLoading ? (
<FaClipboard style={{
animation: "pulse 1s ease-in-out infinite",
opacity: 0.7
@@ -113,7 +114,12 @@ export function SmartClipboardButton({
) : (
<FaClipboard />
)}
- <div>{isLoading ? "Copying..." : buttonText}</div>
+ <div style={{
+ color: showSuccess ? "#4CAF50" : "inherit",
+ fontWeight: showSuccess ? "bold" : "normal"
+ }}>
+ {showSuccess ? "Copied to clipboard" : isLoading ? "Copying..." : buttonText}
+ </div>
</div>
</ButtonItem>
<style>{`