summaryrefslogtreecommitdiff
path: root/src/hooks
diff options
context:
space:
mode:
Diffstat (limited to 'src/hooks')
-rw-r--r--src/hooks/useGameConfiguration.ts43
-rw-r--r--src/hooks/useLsfgHooks.ts33
2 files changed, 47 insertions, 29 deletions
diff --git a/src/hooks/useGameConfiguration.ts b/src/hooks/useGameConfiguration.ts
index 3260019..a3976a0 100644
--- a/src/hooks/useGameConfiguration.ts
+++ b/src/hooks/useGameConfiguration.ts
@@ -1,13 +1,22 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useQuickAccessVisible } from "@decky/api";
import { Router } from "@decky/ui";
-import { ensureFlatpakSupport, getGameConfigs, getInstalledGames, getWorkaroundState, removeWorkaroundState, repairFlatpakSupport, resetGameConfig, resetAllGameConfigs, setWorkaroundState, updateGameConfig, type GameConfigEntry, type GlobalConfig, type InstalledGame, type WorkaroundState } from "../api/lsfgApi";
+import { getGameConfigs, getInstalledGames, getWorkaroundState, removeWorkaroundState, resetGameConfig, resetAllGameConfigs, setWorkaroundState, updateGameConfig, 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";
export interface GameTarget extends InstalledGame { configured: boolean; }
+function shortcutTransport(executable: unknown): InstalledGame["transport"] {
+ const target = typeof executable === "string" ? executable.trim() : "";
+ return target === "/usr/bin/flatpak"
+ || target === '"~/.lsfg" "/usr/bin/flatpak"'
+ || target === "~/.lsfg /usr/bin/flatpak"
+ ? { kind: "flatpak" }
+ : { kind: "host" };
+}
+
async function getSteamShortcuts(): Promise<InstalledGame[]> {
const apps = (globalThis as any).SteamClient?.Apps;
if (typeof apps?.GetAllShortcuts !== "function") return [];
@@ -19,11 +28,12 @@ async function getSteamShortcuts(): Promise<InstalledGame[]> {
const appid = Number(shortcut?.appid);
const name = shortcut?.data?.strAppName;
if (!Number.isInteger(appid) || appid === 0 || typeof name !== "string" || !name) return [];
+ const executable = shortcut?.data?.strShortcutExe ?? shortcut?.data?.strExe ?? shortcut?.data?.exe;
return [{
appid: String(appid >>> 0),
name,
nonSteam: true,
- transport: { kind: "host" },
+ transport: shortcutTransport(executable),
}];
});
} catch {
@@ -116,19 +126,6 @@ export function useGameConfiguration() {
const template = useMemo(() => ({ ...getDefaults(), ...globalConfig }), [globalConfig]);
const config = games.find((game) => game.appid === selectedAppId)?.config || template;
- const ensureTargetFlatpakSupport = useCallback(async (target: GameTarget): Promise<boolean> => {
- if (target.transport.kind !== "flatpak") return true;
- const result = await ensureFlatpakSupport(target.transport.flatpakAppId);
- if (!result.success || result.support_status !== "ready") {
- showErrorToast(
- "Flatpak support unavailable",
- result.error || result.message || "The required Flatpak runtime extension is not ready",
- );
- return false;
- }
- return true;
- }, []);
-
const ensureTargetWorkarounds = useCallback(async (target: GameTarget): Promise<boolean> => {
if (!installedGames.some((game) => game.appid === target.appid)) return true;
const appId = Number(target.appid);
@@ -228,19 +225,17 @@ export function useGameConfiguration() {
const enable = useCallback(async (appid: string) => {
const target = targets.find((item) => item.appid === appid);
if (!target?.name) return false;
- if (!(await ensureTargetFlatpakSupport(target))) return false;
if (!(await ensureTargetWorkarounds(target))) return false;
const result = await updateGameConfig(appid, target.name, template);
if (result.success) await load();
else await removeTargetWorkarounds(target);
return result.success;
- }, [ensureTargetFlatpakSupport, ensureTargetWorkarounds, load, removeTargetWorkarounds, targets, template]);
+ }, [ensureTargetWorkarounds, load, removeTargetWorkarounds, targets, template]);
const enableAll = useCallback(async (): Promise<void> => {
const available = targets.filter((target) => !target.configured && target.name);
if (available.length === 0) return;
for (const target of available) {
- if (!(await ensureTargetFlatpakSupport(target))) return;
if (!(await ensureTargetWorkarounds(target))) return;
const result = await updateGameConfig(target.appid, target.name, template);
if (!result.success) {
@@ -253,20 +248,10 @@ export function useGameConfiguration() {
}
}
await load();
- }, [ensureTargetFlatpakSupport, ensureTargetWorkarounds, load, removeTargetWorkarounds, targets, template]);
+ }, [ensureTargetWorkarounds, load, removeTargetWorkarounds, targets, template]);
const repair = useCallback(async (appid: string): Promise<boolean> => {
const target = targets.find((item) => item.appid === appid);
if (!target) return false;
- if (target.transport.kind === "flatpak") {
- const support = await repairFlatpakSupport(target.transport.flatpakAppId);
- if (!support.success || support.support_status !== "ready") {
- showErrorToast(
- "Flatpak support unavailable",
- support.error || support.message || "The required Flatpak runtime extension is not ready",
- );
- return false;
- }
- }
const success = await ensureTargetWorkarounds(target);
if (success) await load();
return success;
diff --git a/src/hooks/useLsfgHooks.ts b/src/hooks/useLsfgHooks.ts
index 9beb749..16f8962 100644
--- a/src/hooks/useLsfgHooks.ts
+++ b/src/hooks/useLsfgHooks.ts
@@ -1,9 +1,12 @@
import { useEffect, useState } from "react";
import {
checkLsfgVkInstalled,
+ getFlatpakSupportStatus,
getLosslessScalingBranchStatus,
installLsfgVk,
+ repairFlatpakSupport,
uninstallLsfgVk,
+ type FlatpakExtensionStatus,
type SteamBranchStatus,
} from "../api/lsfgApi";
import {
@@ -11,6 +14,7 @@ import {
showInstallSuccessToast,
showUninstallErrorToast,
showUninstallSuccessToast,
+ showErrorToast,
} from "../utils/toastUtils";
export function useInstallation(reloadConfig?: () => Promise<void>) {
@@ -18,12 +22,20 @@ export function useInstallation(reloadConfig?: () => Promise<void>) {
const [installationStatus, setInstallationStatus] = useState("");
const [losslessScalingInstalled, setLosslessScalingInstalled] = useState(false);
const [losslessScalingStatus, setLosslessScalingStatus] = useState("");
+ const [flatpakStatus, setFlatpakStatus] = useState<FlatpakExtensionStatus | null>(null);
const [steamBranchStatus, setSteamBranchStatus] = useState<SteamBranchStatus | null>(null);
const [isInstalling, setIsInstalling] = useState(false);
const [isUninstalling, setIsUninstalling] = useState(false);
+ const [isRepairingFlatpak, setIsRepairingFlatpak] = useState(false);
const checkInstallation = async () => {
try {
+ setFlatpakStatus(await getFlatpakSupportStatus());
+ } catch (error) {
+ console.error("Error checking Flatpak support:", error);
+ setFlatpakStatus(null);
+ }
+ try {
setSteamBranchStatus(await getLosslessScalingBranchStatus());
} catch (error) {
console.error("Error checking Lossless Scaling Steam branch:", error);
@@ -95,16 +107,37 @@ export function useInstallation(reloadConfig?: () => Promise<void>) {
}
};
+ const repairFlatpak = async () => {
+ if (isRepairingFlatpak) return false;
+ setIsRepairingFlatpak(true);
+ try {
+ const result = await repairFlatpakSupport();
+ setFlatpakStatus(result);
+ if (!result.success) {
+ showErrorToast("Flatpak support repair failed", result.error || result.message || "Unknown error");
+ }
+ return result.success;
+ } catch (error) {
+ showErrorToast("Flatpak support repair failed", String(error));
+ return false;
+ } finally {
+ setIsRepairingFlatpak(false);
+ }
+ };
+
return {
isInstalled,
installationStatus,
losslessScalingInstalled,
losslessScalingStatus,
+ flatpakStatus,
steamBranchStatus,
isInstalling,
isUninstalling,
+ isRepairingFlatpak,
install,
uninstall,
+ repairFlatpak,
checkInstallation,
};
}