summaryrefslogtreecommitdiff
path: root/src/hooks
diff options
context:
space:
mode:
Diffstat (limited to 'src/hooks')
-rw-r--r--src/hooks/useGameConfiguration.ts46
-rw-r--r--src/hooks/useLsfgHooks.ts9
-rw-r--r--src/hooks/usePerAppWorkarounds.ts2
3 files changed, 54 insertions, 3 deletions
diff --git a/src/hooks/useGameConfiguration.ts b/src/hooks/useGameConfiguration.ts
index 2e39f5e..fd8dfb1 100644
--- a/src/hooks/useGameConfiguration.ts
+++ b/src/hooks/useGameConfiguration.ts
@@ -1,7 +1,7 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useQuickAccessVisible } from "@decky/api";
import { Router } from "@decky/ui";
-import { getGameConfigs, getInstalledGames, getWorkaroundState, removeWorkaroundState, resetGameConfig, resetAllGameConfigs, setWorkaroundState, updateGameConfig, type GameConfigEntry, type GlobalConfig, type InstalledGame, type WorkaroundState } from "../api/lsfgApi";
+import { getGameConfigs, getInstalledGames, getWorkaroundApps, getWorkaroundState, removeWorkaroundState, resetGameConfig, resetAllGameConfigs, setWorkaroundState, updateGameConfig, updateGlobalConfig as saveGlobalConfig, type GameConfigEntry, type GlobalConfig, type InstalledGame, type WorkaroundState } from "../api/lsfgApi";
import { ConfigurationData, getDefaults } from "../config/configSchema";
import { getDefaultWrapperPath, installWrapperIntegration, removeWrapperIntegration } from "../utils/steamLaunchOptions";
import { showErrorToast } from "../utils/toastUtils";
@@ -153,6 +153,7 @@ export function useGameConfiguration() {
target.appid,
state,
integration.commandTokenAdded,
+ target.nonSteam,
);
if (!saved.success) throw new Error(saved.error || "Could not save workaround state");
return true;
@@ -205,6 +206,40 @@ export function useGameConfiguration() {
}
}, [installedGames]);
+ const cleanupAllWorkarounds = useCallback(async (): Promise<boolean> => {
+ try {
+ const result = await getWorkaroundApps();
+ if (!result.success) throw new Error(result.error || "Could not read workaround state");
+ const targetsByAppId = new Map(targets.map((target) => [target.appid, target]));
+ const cleaned = new Set<string>();
+ const wrapperPath = result.wrapper_path || getDefaultWrapperPath();
+
+ for (const entry of result.apps || []) {
+ const target = targetsByAppId.get(entry.appid);
+ const nonSteam = target?.nonSteam ?? entry.non_steam;
+ await removeWrapperIntegration(
+ Number(entry.appid),
+ nonSteam,
+ wrapperPath,
+ entry.command_token_added,
+ );
+ const removed = await removeWorkaroundState(entry.appid);
+ if (!removed.success) throw new Error(removed.error || "Could not remove workaround state");
+ cleaned.add(entry.appid);
+ }
+
+ // Also clean configured targets whose sidecar entry was lost. This
+ // removes an old wrapper and only the plugin-managed launch pieces.
+ for (const target of targets.filter((item) => item.configured && installedGames.some((game) => game.appid === item.appid))) {
+ if (!cleaned.has(target.appid) && !(await removeTargetWorkarounds(target))) return false;
+ }
+ return true;
+ } catch (error) {
+ showErrorToast("Could not clean up game launch options", asError(error).message);
+ return false;
+ }
+ }, [installedGames, removeTargetWorkarounds, targets]);
+
const saveFor = useCallback(async (appid: string, next: ConfigurationData, cleanupLaunchOptions = false) => {
const target = targets.find((item) => item.appid === appid);
if (!target?.name) return false;
@@ -222,6 +257,13 @@ export function useGameConfiguration() {
[saveFor, selectedAppId],
);
+ const updateGlobal = useCallback(async (next: GlobalConfig): Promise<boolean> => {
+ const result = await saveGlobalConfig(next);
+ if (!result.success) return false;
+ setGlobalConfig(result.global_config || next);
+ return true;
+ }, []);
+
const enable = useCallback(async (appid: string) => {
const target = targets.find((item) => item.appid === appid);
if (!target?.name) return false;
@@ -283,5 +325,5 @@ export function useGameConfiguration() {
}
}, [load, removeTargetWorkarounds, targets]);
- return { config, runningConfig, games, targets, runningGame, selectedAppId, setSelectedAppId, save, saveFor, enable, enableAll, repair, resetSelected, resetAll, reload: load };
+ return { config, runningConfig, globalConfig, targets, runningGame, selectedAppId, setSelectedAppId, save, saveFor, updateGlobal, enable, enableAll, repair, resetSelected, resetAll, cleanupAllWorkarounds, reload: load };
}
diff --git a/src/hooks/useLsfgHooks.ts b/src/hooks/useLsfgHooks.ts
index 9beb749..0f51e90 100644
--- a/src/hooks/useLsfgHooks.ts
+++ b/src/hooks/useLsfgHooks.ts
@@ -13,7 +13,10 @@ import {
showUninstallSuccessToast,
} from "../utils/toastUtils";
-export function useInstallation(reloadConfig?: () => Promise<void>) {
+export function useInstallation(
+ reloadConfig?: () => Promise<void>,
+ beforeUninstall?: () => Promise<boolean>,
+) {
const [isInstalled, setIsInstalled] = useState(false);
const [installationStatus, setInstallationStatus] = useState("");
const [losslessScalingInstalled, setLosslessScalingInstalled] = useState(false);
@@ -77,6 +80,10 @@ export function useInstallation(reloadConfig?: () => Promise<void>) {
setIsUninstalling(true);
setInstallationStatus("Uninstalling lsfg-vk...");
try {
+ if (beforeUninstall && !(await beforeUninstall())) {
+ setInstallationStatus("Uninstallation cancelled: could not clean up launch options");
+ return;
+ }
const result = await uninstallLsfgVk();
if (!result.success) {
setInstallationStatus(`Uninstallation failed: ${result.error}`);
diff --git a/src/hooks/usePerAppWorkarounds.ts b/src/hooks/usePerAppWorkarounds.ts
index c2b8904..ab33bb2 100644
--- a/src/hooks/usePerAppWorkarounds.ts
+++ b/src/hooks/usePerAppWorkarounds.ts
@@ -86,6 +86,7 @@ async function adoptWorkaroundState(
appId,
DEFAULT_WORKAROUND_STATE,
integration.commandTokenAdded,
+ nonSteam,
);
if (!finalized.success) throw new Error(finalized.error || "Could not finalize workaround state");
return makeSnapshot(integration.snapshot, finalized, nonSteam);
@@ -206,6 +207,7 @@ export function usePerAppWorkarounds(appId: string, nonSteam: boolean): PerAppWo
appId,
nextState,
current.commandTokenAdded,
+ nonSteam,
);
if (!result.success || !result.state) throw new Error(result.error || "Could not save workaround state");
applySnapshot({