From 0da3682755e551a7d3c23fa979686d8dbcdd4f7b Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Mon, 22 Sep 2025 09:38:20 -0400 Subject: bring forward old flatpak modal attempt --- src/components/FlatpaksModal.tsx | 291 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) (limited to 'src/components/FlatpaksModal.tsx') diff --git a/src/components/FlatpaksModal.tsx b/src/components/FlatpaksModal.tsx index e69de29..a57c683 100644 --- a/src/components/FlatpaksModal.tsx +++ b/src/components/FlatpaksModal.tsx @@ -0,0 +1,291 @@ +import { FC, useState, useEffect } from 'react'; +import { + ModalRoot, + DialogBody, + DialogHeader, + DialogControlsSection, + DialogControlsSectionHeader, + ButtonItem, + PanelSectionRow, + Field, + Toggle, + Spinner, + Focusable, + showModal, + ConfirmModal +} from '@decky/ui'; +import { FaCheck, FaTimes, FaDownload, FaTrash, FaCog } from 'react-icons/fa'; +import { + checkFlatpakExtensionStatus, + installFlatpakExtension, + uninstallFlatpakExtension, + getFlatpakApps, + setFlatpakAppOverride, + removeFlatpakAppOverride, + FlatpakExtensionStatus, + FlatpakApp, + FlatpakAppInfo +} from '../api/lsfgApi'; + +interface FlatpaksModalProps { + closeModal?: () => void; +} + +const FlatpaksModal: FC = ({ closeModal }) => { + const [extensionStatus, setExtensionStatus] = useState(null); + const [flatpakApps, setFlatpakApps] = useState(null); + const [loading, setLoading] = useState(true); + const [operationInProgress, setOperationInProgress] = useState(null); + + const loadData = async () => { + setLoading(true); + try { + const [statusResult, appsResult] = await Promise.all([ + checkFlatpakExtensionStatus(), + getFlatpakApps() + ]); + + setExtensionStatus(statusResult); + setFlatpakApps(appsResult); + } catch (error) { + console.error('Error loading Flatpak data:', error); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + loadData(); + }, []); + + const handleExtensionOperation = async (operation: 'install' | 'uninstall', version: string) => { + const operationId = `${operation}-${version}`; + setOperationInProgress(operationId); + + try { + const result = operation === 'install' + ? await installFlatpakExtension(version) + : await uninstallFlatpakExtension(version); + + if (result.success) { + // Reload status after operation + const newStatus = await checkFlatpakExtensionStatus(); + setExtensionStatus(newStatus); + } + } catch (error) { + console.error(`Error ${operation}ing extension:`, error); + } finally { + setOperationInProgress(null); + } + }; + + const handleAppOverrideToggle = async (app: FlatpakApp) => { + const hasOverrides = app.has_filesystem_override && app.has_env_override; + const operationId = `app-${app.app_id}`; + setOperationInProgress(operationId); + + try { + const result = hasOverrides + ? await removeFlatpakAppOverride(app.app_id) + : await setFlatpakAppOverride(app.app_id); + + if (result.success) { + // Reload apps data after operation + const newApps = await getFlatpakApps(); + setFlatpakApps(newApps); + } + } catch (error) { + console.error('Error toggling app override:', error); + } finally { + setOperationInProgress(null); + } + }; + + const confirmOperation = (operation: () => void, title: string, description: string) => { + showModal( + {}} + /> + ); + }; + + if (loading) { + return ( + + Flatpak Extensions + +
+ +
+
+
+ ); + } + + return ( + + Flatpak Extensions + + + {/* Extension Status Section */} + + Runtime Extensions + + {extensionStatus && extensionStatus.success ? ( + <> + {/* 23.08 Runtime */} + + : } + > + { + const operation = extensionStatus.installed_23_08 ? 'uninstall' : 'install'; + const action = () => handleExtensionOperation(operation, '23.08'); + + if (operation === 'uninstall') { + confirmOperation( + action, + 'Uninstall Runtime Extension', + 'Are you sure you want to uninstall the 23.08 runtime extension?' + ); + } else { + action(); + } + }} + disabled={operationInProgress === 'install-23.08' || operationInProgress === 'uninstall-23.08'} + > + {operationInProgress === 'install-23.08' || operationInProgress === 'uninstall-23.08' ? ( + + ) : extensionStatus.installed_23_08 ? ( + <> + Uninstall + + ) : ( + <> + Install + + )} + + + + + {/* 24.08 Runtime */} + + : } + > + { + const operation = extensionStatus.installed_24_08 ? 'uninstall' : 'install'; + const action = () => handleExtensionOperation(operation, '24.08'); + + if (operation === 'uninstall') { + confirmOperation( + action, + 'Uninstall Runtime Extension', + 'Are you sure you want to uninstall the 24.08 runtime extension?' + ); + } else { + action(); + } + }} + disabled={operationInProgress === 'install-24.08' || operationInProgress === 'uninstall-24.08'} + > + {operationInProgress === 'install-24.08' || operationInProgress === 'uninstall-24.08' ? ( + + ) : extensionStatus.installed_24_08 ? ( + <> + Uninstall + + ) : ( + <> + Install + + )} + + + + + ) : ( + + } + /> + + )} + + + {/* Flatpak Apps Section */} + + Flatpak Applications + + {flatpakApps && flatpakApps.success ? ( + flatpakApps.apps.length > 0 ? ( + flatpakApps.apps.map((app) => { + const hasOverrides = app.has_filesystem_override && app.has_env_override; + const partialOverrides = app.has_filesystem_override || app.has_env_override; + + let statusColor = 'red'; + let statusText = 'No overrides'; + + if (hasOverrides) { + statusColor = 'green'; + statusText = 'Configured'; + } else if (partialOverrides) { + statusColor = 'orange'; + statusText = 'Partial'; + } + + return ( + + } + > + handleAppOverrideToggle(app)} + disabled={operationInProgress === `app-${app.app_id}`} + /> + + + ); + }) + ) : ( + + + + ) + ) : ( + + } + /> + + )} + + + + + ); +}; + +export default FlatpaksModal; -- cgit v1.2.3 From 427e3f7295f91c5c05cbc15be2ed0a2d714ebdb0 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Mon, 22 Sep 2025 10:08:20 -0400 Subject: add instructions for launch args --- src/components/FlatpaksModal.tsx | 79 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) (limited to 'src/components/FlatpaksModal.tsx') diff --git a/src/components/FlatpaksModal.tsx b/src/components/FlatpaksModal.tsx index a57c683..963aaf9 100644 --- a/src/components/FlatpaksModal.tsx +++ b/src/components/FlatpaksModal.tsx @@ -132,7 +132,7 @@ const FlatpaksModal: FC = ({ closeModal }) => { {/* Extension Status Section */} - Runtime Extensions + Runtime Extension Installer {extensionStatus && extensionStatus.success ? ( <> @@ -282,6 +282,83 @@ const FlatpaksModal: FC = ({ closeModal }) => { )} + + {/* Steam Configuration Instructions */} + + Steam Configuration + + +
+
+ Configure Steam Flatpak Shortcuts +
+
+ In Steam, open your flatpak game and click the cog wheel." +
+
+ IMPORTANT: Set this in TARGET (NOT LAUNCH OPTIONS) +
+ +
+ Try first: +
+
+ ~/lsfg +
+ +
+ If that doesn't work, try full path: +
+
+ /home/(username)/lsfg +
+ +
+ Final result should look like: +
+
+ ~/lsfg "usr/bin/flatpak" +
+
+
+
+ + {/* Close Button */} + + + + Close + + +
-- cgit v1.2.3 From 5a8e0457f1ceeed63af69a620000aaff986a1831 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Mon, 22 Sep 2025 10:18:36 -0400 Subject: feat: add picture example for flatpak shortcut hooking --- src/components/FlatpaksModal.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/components/FlatpaksModal.tsx') diff --git a/src/components/FlatpaksModal.tsx b/src/components/FlatpaksModal.tsx index 963aaf9..bd81013 100644 --- a/src/components/FlatpaksModal.tsx +++ b/src/components/FlatpaksModal.tsx @@ -15,6 +15,7 @@ import { ConfirmModal } from '@decky/ui'; import { FaCheck, FaTimes, FaDownload, FaTrash, FaCog } from 'react-icons/fa'; +import flatpakTargetImage from '../../assets/flatpak-target.png'; import { checkFlatpakExtensionStatus, installFlatpakExtension, @@ -344,6 +345,20 @@ const FlatpaksModal: FC = ({ closeModal }) => { }}> ~/lsfg "usr/bin/flatpak" + + {/* Visual example image */} +
+ Steam Properties Target Field Example +
-- cgit v1.2.3