From e8e469f99078858dc953663cba6f3428e80b1c5d Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Sat, 5 Sep 2026 23:44:37 -0400 Subject: refactor: delegate runtime checks to lsfg-vk --- src/api/lsfgApi.ts | 27 ++------------- src/components/Content.tsx | 21 ++++++------ src/components/FlatpaksModal.tsx | 67 +++++++++++++++++++++++++++++++++++++ src/components/NerdStuffModal.tsx | 55 +++++------------------------- src/components/StatusDisplay.tsx | 21 +++++++----- src/hooks/useInstallationActions.ts | 12 +++++-- src/hooks/useLsfgHooks.ts | 37 +++++--------------- src/i18n/languages.json | 12 ------- 8 files changed, 120 insertions(+), 132 deletions(-) (limited to 'src') diff --git a/src/api/lsfgApi.ts b/src/api/lsfgApi.ts index 2c9f4a9..68cf6bf 100644 --- a/src/api/lsfgApi.ts +++ b/src/api/lsfgApi.ts @@ -11,28 +11,8 @@ export interface InstallationResult { export interface InstallationStatus { installed: boolean; - lib_exists: boolean; - json_exists: boolean; - script_exists: boolean; - lib_path: string; - json_path: string; - script_path: string; - error?: string; -} - -export interface DllDetectionResult { - detected: boolean; - path?: string; - source?: string; - message?: string; - error?: string; -} - -export interface DllStatsResult { - success: boolean; - dll_path?: string; - dll_sha256?: string; - dll_source?: string; + lossless_scaling_installed: boolean; + lossless_scaling_status: string; error?: string; } @@ -84,6 +64,7 @@ export interface FlatpakExtensionStatus { success: boolean; message: string; error?: string; + installed_23_08: boolean; installed_24_08: boolean; installed_25_08: boolean; } @@ -131,8 +112,6 @@ export interface ProfileResult { export const installLsfgVk = callable<[], InstallationResult>("install_lsfg_vk"); export const uninstallLsfgVk = callable<[], InstallationResult>("uninstall_lsfg_vk"); export const checkLsfgVkInstalled = callable<[], InstallationStatus>("check_lsfg_vk_installed"); -export const checkLosslessScalingDll = callable<[], DllDetectionResult>("check_lossless_scaling_dll"); -export const getDllStats = callable<[], DllStatsResult>("get_dll_stats"); export const getLsfgConfig = callable<[], ConfigResult>("get_lsfg_config"); export const getConfigSchema = callable<[], ConfigSchemaResult>("get_config_schema"); export const getLaunchOption = callable<[], LaunchOptionResult>("get_launch_option"); diff --git a/src/components/Content.tsx b/src/components/Content.tsx index 5988e79..aab2fb8 100644 --- a/src/components/Content.tsx +++ b/src/components/Content.tsx @@ -1,6 +1,6 @@ import { useEffect } from "react"; import { PanelSection, showModal, ButtonItem, PanelSectionRow } from "@decky/ui"; -import { useInstallationStatus, useDllDetection, useLsfgConfig } from "../hooks/useLsfgHooks"; +import { useInstallationStatus, useLsfgConfig } from "../hooks/useLsfgHooks"; import { useProfileManagement } from "../hooks/useProfileManagement"; import { useInstallationActions } from "../hooks/useInstallationActions"; import { StatusDisplay } from "./StatusDisplay"; @@ -21,11 +21,12 @@ export function Content() { isInstalled, installationStatus, setIsInstalled, - setInstallationStatus + setInstallationStatus, + losslessScalingInstalled, + losslessScalingStatus, + checkInstallation } = useInstallationStatus(); - const { dllDetected, dllDetectionStatus } = useDllDetection(); - const { config, loadLsfgConfig, @@ -59,11 +60,11 @@ export function Content() { }; const onInstall = () => { - handleInstall(setIsInstalled, setInstallationStatus, loadLsfgConfig); + handleInstall(setIsInstalled, setInstallationStatus, loadLsfgConfig, checkInstallation); }; const onUninstall = () => { - handleUninstall(setIsInstalled, setInstallationStatus); + handleUninstall(setIsInstalled, setInstallationStatus, checkInstallation); }; const handleShowNerdStuff = () => { @@ -87,10 +88,10 @@ export function Content() { /> )} @@ -167,10 +168,10 @@ export function Content() { {isInstalled && ( <> void; @@ -38,6 +39,7 @@ export const FlatpaksModal: FC = ({ closeModal }) => { const [flatpakApps, setFlatpakApps] = useState(null); const [loading, setLoading] = useState(true); const [operationInProgress, setOperationInProgress] = useState(null); + const [operationError, setOperationError] = useState(null); const loadData = async () => { setLoading(true); @@ -63,6 +65,7 @@ export const FlatpaksModal: FC = ({ closeModal }) => { const handleExtensionOperation = async (operation: 'install' | 'uninstall', version: string) => { const operationId = `${operation}-${version}`; setOperationInProgress(operationId); + setOperationError(null); try { const result = operation === 'install' @@ -73,9 +76,16 @@ export const FlatpaksModal: FC = ({ closeModal }) => { // Reload status after operation const newStatus = await checkFlatpakExtensionStatus(); setExtensionStatus(newStatus); + } else { + const message = result.error || result.message || 'Flatpak operation failed'; + setOperationError(message); + showErrorToast('Flatpak operation failed', message); } } catch (error) { console.error(`Error ${operation}ing extension:`, error); + const message = String(error); + setOperationError(message); + showErrorToast('Flatpak operation failed', message); } finally { setOperationInProgress(null); } @@ -85,6 +95,7 @@ export const FlatpaksModal: FC = ({ closeModal }) => { const hasOverrides = app.has_filesystem_override && app.has_env_override; const operationId = `app-${app.app_id}`; setOperationInProgress(operationId); + setOperationError(null); try { const result = hasOverrides @@ -95,9 +106,16 @@ export const FlatpaksModal: FC = ({ closeModal }) => { // Reload apps data after operation const newApps = await getFlatpakApps(); setFlatpakApps(newApps); + } else { + const message = result.error || result.message || 'Flatpak override failed'; + setOperationError(message); + showErrorToast('Flatpak override failed', message); } } catch (error) { console.error('Error toggling app override:', error); + const message = String(error); + setOperationError(message); + showErrorToast('Flatpak override failed', message); } finally { setOperationInProgress(null); } @@ -170,8 +188,57 @@ export const FlatpaksModal: FC = ({ closeModal }) => { {t('FLATPAK_RUNTIME_INSTALLER', 'Runtime Extension Installer')} + {operationError && ( + + } + /> + + )} + {extensionStatus && extensionStatus.success ? ( <> + + : } + > + { + const operation = extensionStatus.installed_23_08 ? 'uninstall' : 'install'; + const action = () => handleExtensionOperation(operation, '23.08'); + + if (operation === 'uninstall') { + confirmOperation( + action, + t('FLATPAK_UNINSTALL_TITLE', 'Uninstall Runtime Extension'), + `${t('FLATPAK_UNINSTALL_CONFIRM_PREFIX', 'Are you sure you want to uninstall the')} 23.08 ${t('FLATPAK_UNINSTALL_CONFIRM_SUFFIX', '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 ? ( + <> + {t('FLATPAK_UNINSTALL_BTN', 'Uninstall')} + + ) : ( + <> + {t('FLATPAK_INSTALL_BTN', 'Install')} + + )} + + + + {/* 24.08 Runtime */} (null); const [configContent, setConfigContent] = useState(null); const [scriptContent, setScriptContent] = useState(null); const [loading, setLoading] = useState(true); @@ -28,13 +31,11 @@ export function NerdStuffModal({ closeModal }: NerdStuffModalProps) { setError(null); // Load all data in parallel - const [dllResult, configResult, scriptResult] = await Promise.all([ - getDllStats(), + const [configResult, scriptResult] = await Promise.all([ getConfigFileContent(), - getLaunchScriptContent() + getLaunchScriptContent(), ]); - setDllStats(dllResult); setConfigContent(configResult); setScriptContent(scriptResult); } catch (err) { @@ -47,11 +48,6 @@ export function NerdStuffModal({ closeModal }: NerdStuffModalProps) { loadData(); }, []); - const formatSHA256 = (hash: string) => { - // Format SHA256 hash for better readability (add spaces every 8 characters) - return hash.replace(/(.{8})/g, '$1 ').trim(); - }; - const copyToClipboard = async (text: string) => { try { await navigator.clipboard.writeText(text); @@ -73,41 +69,6 @@ export function NerdStuffModal({ closeModal }: NerdStuffModalProps) { {!loading && !error && ( <> - {/* DLL Stats Section */} - {dllStats && ( - <> - {!dllStats.success ? ( -
{dllStats.error || "Failed to get DLL stats"}
- ) : ( -
- - dllStats.dll_path && copyToClipboard(dllStats.dll_path)} - onActivate={() => dllStats.dll_path && copyToClipboard(dllStats.dll_path)} - > - {dllStats.dll_path || t('NERD_NOT_AVAILABLE', 'Not available')} - - - - - dllStats.dll_sha256 && copyToClipboard(dllStats.dll_sha256)} - onActivate={() => dllStats.dll_sha256 && copyToClipboard(dllStats.dll_sha256)} - > - {dllStats.dll_sha256 ? formatSHA256(dllStats.dll_sha256) : t('NERD_NOT_AVAILABLE', 'Not available')} - - - - {dllStats.dll_source && ( - -
{dllStats.dll_source}
-
- )} -
- )} - - )} - {/* Launch Script Section */} {scriptContent && ( @@ -168,7 +129,7 @@ export function NerdStuffModal({ closeModal }: NerdStuffModalProps) { )} )} - + {/* Close Button */} diff --git a/src/components/StatusDisplay.tsx b/src/components/StatusDisplay.tsx index 3a48a15..31584eb 100644 --- a/src/components/StatusDisplay.tsx +++ b/src/components/StatusDisplay.tsx @@ -1,24 +1,24 @@ import { PanelSectionRow } from "@decky/ui"; interface StatusDisplayProps { - dllDetected: boolean; - dllDetectionStatus: string; isInstalled: boolean; installationStatus: string; + losslessScalingInstalled: boolean; + losslessScalingStatus: string; } export function StatusDisplay({ - dllDetected, - dllDetectionStatus, isInstalled, - installationStatus + installationStatus, + losslessScalingInstalled, + losslessScalingStatus }: StatusDisplayProps) { return (
- {dllDetected ? "✅" : "❌"} + {losslessScalingInstalled ? "✅" : "❌"} - {dllDetectionStatus} + {losslessScalingInstalled ? "Lossless Scaling Installed" : "Lossless Scaling Not Installed"}
+ {!losslessScalingInstalled && losslessScalingStatus && ( +
+ {losslessScalingStatus} +
+ )}
void, setInstallationStatus: (value: string) => void, - reloadConfig?: () => Promise + reloadConfig?: () => Promise, + reloadStatus?: () => Promise ) => { setIsInstalling(true); setInstallationStatus("Installing lsfg-vk..."); @@ -30,6 +31,9 @@ export function useInstallationActions() { if (reloadConfig) { await reloadConfig(); } + if (reloadStatus) { + await reloadStatus(); + } } else { setInstallationStatus(`Installation failed: ${result.error}`); showInstallErrorToast(result.error); @@ -44,7 +48,8 @@ export function useInstallationActions() { const handleUninstall = async ( setIsInstalled: (value: boolean) => void, - setInstallationStatus: (value: string) => void + setInstallationStatus: (value: string) => void, + reloadStatus?: () => Promise ) => { setIsUninstalling(true); setInstallationStatus("Uninstalling lsfg-vk..."); @@ -54,6 +59,9 @@ export function useInstallationActions() { if (result.success) { setIsInstalled(false); setInstallationStatus("lsfg-vk uninstalled successfully!"); + if (reloadStatus) { + await reloadStatus(); + } showUninstallSuccessToast(); } else { setInstallationStatus(`Uninstallation failed: ${result.error}`); diff --git a/src/hooks/useLsfgHooks.ts b/src/hooks/useLsfgHooks.ts index d9bbe3e..597110e 100644 --- a/src/hooks/useLsfgHooks.ts +++ b/src/hooks/useLsfgHooks.ts @@ -1,7 +1,6 @@ import { useState, useEffect, useCallback } from "react"; import { checkLsfgVkInstalled, - checkLosslessScalingDll, getLsfgConfig, updateLsfgConfigFromObject, type ConfigUpdateResult @@ -12,11 +11,15 @@ import { showErrorToast, ToastMessages } from "../utils/toastUtils"; export function useInstallationStatus() { const [isInstalled, setIsInstalled] = useState(false); const [installationStatus, setInstallationStatus] = useState(""); + const [losslessScalingInstalled, setLosslessScalingInstalled] = useState(false); + const [losslessScalingStatus, setLosslessScalingStatus] = useState(""); const checkInstallation = async () => { try { const status = await checkLsfgVkInstalled(); setIsInstalled(status.installed); + setLosslessScalingInstalled(status.lossless_scaling_installed); + setLosslessScalingStatus(status.lossless_scaling_status || "Lossless Scaling Not Installed"); if (status.installed) { setInstallationStatus("lsfg-vk Installed"); } else { @@ -24,6 +27,8 @@ export function useInstallationStatus() { } return status.installed; } catch (error) { + setLosslessScalingInstalled(false); + setLosslessScalingStatus("Lossless Scaling Not Installed"); setInstallationStatus("lsfg-vk Not Installed"); return false; } @@ -38,38 +43,12 @@ export function useInstallationStatus() { installationStatus, setIsInstalled, setInstallationStatus, + losslessScalingInstalled, + losslessScalingStatus, checkInstallation }; } -export function useDllDetection() { - const [dllDetected, setDllDetected] = useState(false); - const [dllDetectionStatus, setDllDetectionStatus] = useState(""); - - const checkDllDetection = async () => { - try { - const result = await checkLosslessScalingDll(); - setDllDetected(result.detected); - if (result.detected) { - setDllDetectionStatus("Lossless Scaling Installed"); - } else { - setDllDetectionStatus("Lossless Scaling Not Installed"); - } - } catch (error) { - setDllDetectionStatus("Lossless Scaling Not Installed"); - } - }; - - useEffect(() => { - checkDllDetection(); - }, []); - - return { - dllDetected, - dllDetectionStatus - }; -} - export function useLsfgConfig() { const [config, setConfig] = useState(() => getDefaults()); diff --git a/src/i18n/languages.json b/src/i18n/languages.json index c1a49b8..46b4cd9 100644 --- a/src/i18n/languages.json +++ b/src/i18n/languages.json @@ -67,10 +67,6 @@ "FLATPAK_STEP_FINAL": "最終的な結果はこのようになります:", "FLATPAK_CLOSE": "閉じる", "NERD_LOADING": "情報を読み込み中...", - "NERD_DLL_PATH": "DLLパス", - "NERD_NOT_AVAILABLE": "利用不可", - "NERD_DLL_HASH": "DLL SHA256ハッシュ", - "NERD_DETECTION_SOURCE": "検出ソース", "NERD_LAUNCH_SCRIPT": "起動スクリプト", "NERD_SCRIPT_NOT_FOUND_PREFIX": "スクリプトが見つかりません:", "NERD_PATH_PREFIX": "パス:", @@ -174,10 +170,6 @@ "FLATPAK_STEP_FINAL": "최종 결과는 다음과 같아야 합니다:", "FLATPAK_CLOSE": "닫기", "NERD_LOADING": "정보 불러오는 중...", - "NERD_DLL_PATH": "DLL 경로", - "NERD_NOT_AVAILABLE": "사용 불가", - "NERD_DLL_HASH": "DLL SHA256 해시", - "NERD_DETECTION_SOURCE": "감지 소스", "NERD_LAUNCH_SCRIPT": "실행 스크립트", "NERD_SCRIPT_NOT_FOUND_PREFIX": "스크립트 없음:", "NERD_PATH_PREFIX": "경로:", @@ -309,10 +301,6 @@ "FLATPAK_STEP_FINAL": "Final result should look like:", "FLATPAK_CLOSE": "Close", "NERD_LOADING": "Loading information...", - "NERD_DLL_PATH": "DLL Path", - "NERD_NOT_AVAILABLE": "Not available", - "NERD_DLL_HASH": "DLL SHA256 Hash", - "NERD_DETECTION_SOURCE": "Detection Source", "NERD_LAUNCH_SCRIPT": "Launch Script", "NERD_SCRIPT_NOT_FOUND_PREFIX": "Script not found:", "NERD_PATH_PREFIX": "Path:", -- cgit v1.2.3