summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package.json2
-rw-r--r--src/components/ClipboardButton.tsx6
-rw-r--r--src/components/Content.tsx7
-rw-r--r--src/components/SmartClipboardButton.tsx124
-rw-r--r--src/components/UsageInstructions.tsx2
-rw-r--r--src/components/index.ts2
6 files changed, 134 insertions, 9 deletions
diff --git a/package.json b/package.json
index 2d6fea4..7989109 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "decky-lossless-scaling-vk",
- "version": "0.6.7",
+ "version": "0.6.8",
"description": "Use Lossless Scaling on the Steam Deck using the lsfg-vk vulkan layer",
"type": "module",
"scripts": {
diff --git a/src/components/ClipboardButton.tsx b/src/components/ClipboardButton.tsx
index 7fd0a9b..cac1863 100644
--- a/src/components/ClipboardButton.tsx
+++ b/src/components/ClipboardButton.tsx
@@ -1,5 +1,5 @@
import { PanelSectionRow, ButtonItem } from "@decky/ui";
-import { FaClipboard } from "react-icons/fa";
+import { FaBook } from "react-icons/fa";
export function ClipboardButton() {
const handleClipboardClick = () => {
@@ -13,8 +13,8 @@ export function ClipboardButton() {
onClick={handleClipboardClick}
>
<div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
- <FaClipboard />
- <div>Launch Option Clipboard</div>
+ <FaBook />
+ <div>Plugin Wiki</div>
</div>
</ButtonItem>
</PanelSectionRow>
diff --git a/src/components/Content.tsx b/src/components/Content.tsx
index 9ce4c35..a075574 100644
--- a/src/components/Content.tsx
+++ b/src/components/Content.tsx
@@ -8,6 +8,7 @@ import { ConfigurationSection } from "./ConfigurationSection";
import { UsageInstructions } from "./UsageInstructions";
import { WikiButton } from "./WikiButton";
import { ClipboardButton } from "./ClipboardButton";
+import { SmartClipboardButton } from "./SmartClipboardButton";
import { PluginUpdateChecker } from "./PluginUpdateChecker";
import { NerdStuffModal } from "./NerdStuffModal";
import { ConfigurationData } from "../config/configSchema";
@@ -70,6 +71,8 @@ export function Content() {
isInstalled={isInstalled}
installationStatus={installationStatus}
/>
+
+ <SmartClipboardButton />
{/* Configuration Section - only show if installed */}
{isInstalled && (
@@ -85,9 +88,7 @@ export function Content() {
<ClipboardButton />
{/* Plugin Update Checker */}
- <PluginUpdateChecker />
-
- {/* Nerd Stuff Button */}
+ <PluginUpdateChecker /> {/* Nerd Stuff Button */}
<PanelSectionRow>
<ButtonItem
layout="below"
diff --git a/src/components/SmartClipboardButton.tsx b/src/components/SmartClipboardButton.tsx
new file mode 100644
index 0000000..81223bd
--- /dev/null
+++ b/src/components/SmartClipboardButton.tsx
@@ -0,0 +1,124 @@
+import { useState } from "react";
+import { PanelSectionRow, ButtonItem } from "@decky/ui";
+import { FaClipboard } from "react-icons/fa";
+import { toaster } from "@decky/api";
+import { getLaunchOption } from "../api/lsfgApi";
+
+export function SmartClipboardButton() {
+ const [isLoading, setIsLoading] = useState(false);
+
+ const getLaunchOptionText = async (): Promise<string> => {
+ try {
+ const result = await getLaunchOption();
+ return result.launch_option || "~/lsfg %command%";
+ } catch (error) {
+ return "~/lsfg %command%";
+ }
+ };
+
+ const copyToClipboard = async () => {
+ if (isLoading) return;
+
+ setIsLoading(true);
+ try {
+ const text = await getLaunchOptionText();
+
+ // Use the proven input simulation method
+ const tempInput = document.createElement('input');
+ tempInput.value = text;
+ 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')) {
+ copySuccess = true;
+ }
+ } catch (e) {
+ // If execCommand fails, try navigator.clipboard as fallback
+ try {
+ await navigator.clipboard.writeText(text);
+ copySuccess = true;
+ } catch (clipboardError) {
+ console.error('Both copy methods failed:', e, clipboardError);
+ }
+ }
+
+ // Clean up
+ document.body.removeChild(tempInput);
+
+ if (copySuccess) {
+ // Verify the copy worked by reading back
+ try {
+ const readBack = await navigator.clipboard.readText();
+ if (readBack === text) {
+ toaster.toast({
+ title: "Copied to Clipboard!",
+ body: "Launch option ready to paste"
+ });
+ } else {
+ // Copy worked but verification failed - still consider it success
+ toaster.toast({
+ title: "Copied to Clipboard!",
+ body: "Launch option copied (verification unavailable)"
+ });
+ }
+ } catch (e) {
+ // Verification failed but copy likely worked
+ toaster.toast({
+ title: "Copied to Clipboard!",
+ body: "Launch option copied successfully"
+ });
+ }
+ } else {
+ toaster.toast({
+ title: "Copy Failed",
+ body: "Unable to copy to clipboard"
+ });
+ }
+
+ } catch (error) {
+ toaster.toast({
+ title: "Copy Failed",
+ body: `Error: ${String(error)}`
+ });
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ return (
+ <PanelSectionRow>
+ <ButtonItem
+ layout="below"
+ onClick={copyToClipboard}
+ disabled={isLoading}
+ >
+ <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
+ {isLoading ? (
+ <FaClipboard style={{
+ animation: "pulse 1s ease-in-out infinite",
+ opacity: 0.7
+ }} />
+ ) : (
+ <FaClipboard />
+ )}
+ <div>{isLoading ? "Copying..." : "Copy Launch Option"}</div>
+ </div>
+ </ButtonItem>
+ <style>{`
+ @keyframes pulse {
+ 0% { opacity: 0.7; }
+ 50% { opacity: 1; }
+ 100% { opacity: 0.7; }
+ }
+ `}</style>
+ </PanelSectionRow>
+ );
+}
diff --git a/src/components/UsageInstructions.tsx b/src/components/UsageInstructions.tsx
index 6025241..bcf258b 100644
--- a/src/components/UsageInstructions.tsx
+++ b/src/components/UsageInstructions.tsx
@@ -33,7 +33,7 @@ export function UsageInstructions({ config }: UsageInstructionsProps) {
whiteSpace: "pre-wrap"
}}
>
- Add the launch option below (or use "Launch Option Clipboard") to Steam games to activate frame generation.
+ Click "Copy Launch Option" button, then paste it into your Steam game's launch options to enable frame generation.
</div>
</PanelSectionRow>
diff --git a/src/components/index.ts b/src/components/index.ts
index c0c4804..682598c 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -4,7 +4,7 @@ export { InstallationButton } from "./InstallationButton";
export { ConfigurationSection } from "./ConfigurationSection";
// export { UsageInstructions } from "./UsageInstructions";
export { WikiButton } from "./WikiButton";
-export { ClipboardButton } from "./ClipboardButton";
+export { SmartClipboardButton } from "./SmartClipboardButton";
export { LaunchOptionInfo } from "./LaunchOptionInfo";
export { PluginUpdateChecker } from "./PluginUpdateChecker";
export { NerdStuffModal } from "./NerdStuffModal";