summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--py_modules/lsfg_vk/constants.py2
-rw-r--r--py_modules/lsfg_vk/plugin.py8
-rw-r--r--py_modules/lsfg_vk/steam_service.py273
-rw-r--r--py_modules/lsfg_vk/types.py17
-rw-r--r--src/api/lsfgApi.ts19
-rw-r--r--src/components/Content.tsx22
-rw-r--r--src/components/StatusDisplay.tsx115
-rw-r--r--src/hooks/useLsfgHooks.ts46
8 files changed, 463 insertions, 39 deletions
diff --git a/py_modules/lsfg_vk/constants.py b/py_modules/lsfg_vk/constants.py
index 1f78a59..19df278 100644
--- a/py_modules/lsfg_vk/constants.py
+++ b/py_modules/lsfg_vk/constants.py
@@ -18,6 +18,8 @@ UI_ICON_FILENAME = "gay.pancake.lsfg-vk-ui.png"
FLATPAK_23_08_FILENAME = "org.freedesktop.Platform.VulkanLayer.lsfg_vk_23.08.flatpak"
FLATPAK_24_08_FILENAME = "org.freedesktop.Platform.VulkanLayer.lsfg_vk_24.08.flatpak"
FLATPAK_25_08_FILENAME = "org.freedesktop.Platform.VulkanLayer.lsfg_vk_25.08.flatpak"
+STEAM_LOSSLESS_SCALING_APP_ID = "993090"
+STEAM_LOSSLESS_SCALING_BRANCH = "lsfg-vk"
LEGACY_LIB_FILENAME = "liblsfg-vk.so"
LEGACY_JSON_FILENAME = "VkLayer_LS_frame_generation.json"
diff --git a/py_modules/lsfg_vk/plugin.py b/py_modules/lsfg_vk/plugin.py
index 6a8dfc5..1676566 100644
--- a/py_modules/lsfg_vk/plugin.py
+++ b/py_modules/lsfg_vk/plugin.py
@@ -16,6 +16,7 @@ from .configuration import ConfigurationService
from .config_schema import ConfigurationManager
from .flatpak_service import FlatpakService
from .runtime_service import RuntimeService
+from .steam_service import SteamService
class Plugin:
@@ -33,6 +34,7 @@ class Plugin:
self.installation_service = InstallationService(runtime_service=self.runtime_service)
self.configuration_service = ConfigurationService(runtime_service=self.runtime_service)
self.flatpak_service = FlatpakService()
+ self.steam_service = SteamService()
async def install_lsfg_vk(self) -> Dict[str, Any]:
"""Install the bundled lsfg-vk runtime to ~/.local
@@ -320,6 +322,12 @@ class Plugin:
"""
return self.flatpak_service.get_flatpak_apps()
+ async def get_lossless_scaling_branch_status(self) -> Dict[str, Any]:
+ return self.steam_service.get_branch_status()
+
+ async def select_lossless_scaling_branch(self) -> Dict[str, Any]:
+ return self.steam_service.select_branch()
+
async def set_flatpak_app_override(self, app_id: str) -> Dict[str, Any]:
"""Set lsfg-vk overrides for a Flatpak app
diff --git a/py_modules/lsfg_vk/steam_service.py b/py_modules/lsfg_vk/steam_service.py
new file mode 100644
index 0000000..3278f3c
--- /dev/null
+++ b/py_modules/lsfg_vk/steam_service.py
@@ -0,0 +1,273 @@
+import os
+import re
+import tempfile
+from pathlib import Path
+from typing import Dict, Optional, Tuple
+
+from .base_service import BaseService
+from .constants import STEAM_LOSSLESS_SCALING_APP_ID, STEAM_LOSSLESS_SCALING_BRANCH
+
+
+class SteamService(BaseService):
+ DEFAULT_BRANCH = "public"
+ MANIFEST_FILENAME = f"appmanifest_{STEAM_LOSSLESS_SCALING_APP_ID}.acf"
+
+ def _steam_library_roots(self):
+ candidates = (
+ self.user_home / ".local/share/Steam",
+ self.user_home / ".steam/steam",
+ self.user_home / ".steam/root",
+ self.user_home / ".var/app/com.valvesoftware.Steam/.local/share/Steam",
+ )
+ seen = set()
+
+ for candidate in candidates:
+ yield from self._unique_existing_root(candidate, seen)
+
+ library_file = candidate / "steamapps/libraryfolders.vdf"
+ try:
+ content = library_file.read_text(encoding="utf-8")
+ except OSError:
+ continue
+
+ for raw_path in re.findall(r'(?m)^\s*"path"\s+"((?:\\.|[^"])*)"', content):
+ path = raw_path.replace(r'\"', '"').replace(r'\\', '\\')
+ yield from self._unique_existing_root(Path(path), seen)
+
+ @staticmethod
+ def _unique_existing_root(path: Path, seen: set[str]):
+ if not path.exists():
+ return
+ try:
+ resolved = str(path.resolve())
+ except OSError:
+ resolved = str(path)
+ if resolved in seen:
+ return
+ seen.add(resolved)
+ yield path
+
+ def _manifest_path(self) -> Optional[Path]:
+ for library_root in self._steam_library_roots():
+ manifest = library_root / "steamapps" / self.MANIFEST_FILENAME
+ if manifest.is_file():
+ return manifest
+ return None
+
+ @staticmethod
+ def _section_bounds(content: str, section_name: str) -> Optional[Tuple[int, int, str]]:
+ section = re.search(
+ rf'(?m)^(?P<indent>[ \t]*)"{re.escape(section_name)}"[ \t\r\n]*\{{',
+ content,
+ )
+ if section is None:
+ return None
+
+ depth = 1
+ in_string = False
+ escaped = False
+ for index in range(section.end(), len(content)):
+ character = content[index]
+ if in_string:
+ if escaped:
+ escaped = False
+ elif character == "\\":
+ escaped = True
+ elif character == '"':
+ in_string = False
+ continue
+
+ if character == '"':
+ in_string = True
+ elif character == "{":
+ depth += 1
+ elif character == "}":
+ depth -= 1
+ if depth == 0:
+ return section.end(), index, section.group("indent")
+ return None
+
+ @classmethod
+ def _section_value(cls, content: str, section_name: str, key: str) -> Optional[str]:
+ bounds = cls._section_bounds(content, section_name)
+ if bounds is None:
+ return None
+ body_start, body_end, _ = bounds
+ pattern = re.compile(
+ r'(?m)^[ \t]*"(?P<key>[^"]+)"[ \t]+"(?P<value>(?:\\.|[^"\\])*)"'
+ )
+ for match in pattern.finditer(content, body_start, body_end):
+ if match.group("key") == key:
+ return match.group("value")
+ return None
+
+ @classmethod
+ def _set_section_value(cls, content: str, section_name: str, key: str, value: str) -> str:
+ bounds = cls._section_bounds(content, section_name)
+ if bounds is None:
+ if section_name != "UserConfig":
+ raise ValueError(f"Steam manifest is missing the {section_name} section")
+ app_state = cls._section_bounds(content, "AppState")
+ if app_state is None:
+ raise ValueError("Steam manifest is missing the AppState section")
+ _, app_state_end, app_state_indent = app_state
+ prefix = content[:app_state_end]
+ if not prefix.endswith(("\n", "\r")):
+ prefix += "\n"
+ entry_indent = app_state_indent + "\t"
+ section = (
+ f'{entry_indent}"UserConfig"\n'
+ f'{entry_indent}{{\n'
+ f'{entry_indent}\t"{key}"\t"{value}"\n'
+ f'{entry_indent}}}\n'
+ )
+ return prefix + section + content[app_state_end:]
+
+ body_start, body_end, section_indent = bounds
+ pattern = re.compile(
+ rf'(?m)^[ \t]*"{re.escape(key)}"[ \t]+"(?P<value>(?:\\.|[^"\\])*)"'
+ )
+ match = pattern.search(content, body_start, body_end)
+ if match is not None:
+ return content[: match.start("value")] + value + content[match.end("value") :]
+
+ prefix = content[:body_end]
+ if not prefix.endswith(("\n", "\r")):
+ prefix += "\n"
+ entry_indent = section_indent + "\t"
+ return prefix + f'{entry_indent}"{key}"\t"{value}"\n' + content[body_end:]
+
+ @classmethod
+ def _branch_or_default(cls, branch: Optional[str]) -> str:
+ return branch or cls.DEFAULT_BRANCH
+
+ def _status_fields(self, manifest_path: Path, content: str) -> Dict[str, object]:
+ selected_branch = self._branch_or_default(
+ self._section_value(content, "UserConfig", "BetaKey")
+ )
+ current_branch = self._branch_or_default(
+ self._section_value(content, "MountedConfig", "BetaKey")
+ or self._section_value(content, "UserConfig", "BetaKey")
+ )
+ needs_switch = (
+ selected_branch != STEAM_LOSSLESS_SCALING_BRANCH
+ or current_branch != STEAM_LOSSLESS_SCALING_BRANCH
+ )
+ return {
+ "installed": True,
+ "manifest_path": str(manifest_path),
+ "selected_branch": selected_branch,
+ "current_branch": current_branch,
+ "target_branch": STEAM_LOSSLESS_SCALING_BRANCH,
+ "needs_switch": needs_switch,
+ "restart_required": (
+ selected_branch == STEAM_LOSSLESS_SCALING_BRANCH
+ and current_branch != STEAM_LOSSLESS_SCALING_BRANCH
+ ),
+ }
+
+ def get_branch_status(self) -> Dict[str, object]:
+ try:
+ manifest_path = self._manifest_path()
+ if manifest_path is None:
+ return self._success_response(
+ dict,
+ "Lossless Scaling is not installed through Steam",
+ installed=False,
+ manifest_path=None,
+ selected_branch=None,
+ current_branch=None,
+ target_branch=STEAM_LOSSLESS_SCALING_BRANCH,
+ needs_switch=False,
+ restart_required=False,
+ )
+
+ content = manifest_path.read_text(encoding="utf-8")
+ fields = self._status_fields(manifest_path, content)
+ if not fields["needs_switch"]:
+ message = "Lossless Scaling is using the lsfg-vk Steam branch"
+ elif fields["restart_required"]:
+ message = "lsfg-vk is selected; restart Steam to finish the branch switch"
+ else:
+ message = "Lossless Scaling is not using the lsfg-vk Steam branch"
+ return self._success_response(dict, message, **fields)
+ except Exception as error:
+ return self._error_response(
+ dict,
+ str(error),
+ installed=False,
+ manifest_path=None,
+ selected_branch=None,
+ current_branch=None,
+ target_branch=STEAM_LOSSLESS_SCALING_BRANCH,
+ needs_switch=False,
+ restart_required=False,
+ )
+
+ def select_branch(self) -> Dict[str, object]:
+ try:
+ manifest_path = self._manifest_path()
+ if manifest_path is None:
+ raise FileNotFoundError("Lossless Scaling is not installed through Steam")
+
+ content = manifest_path.read_text(encoding="utf-8")
+ fields = self._status_fields(manifest_path, content)
+ if not fields["needs_switch"]:
+ return self._success_response(
+ dict,
+ "Lossless Scaling is already using the lsfg-vk Steam branch",
+ changed=False,
+ **fields,
+ )
+
+ updated = self._set_section_value(
+ content,
+ "UserConfig",
+ "BetaKey",
+ STEAM_LOSSLESS_SCALING_BRANCH,
+ )
+ if updated != content:
+ file_mode = manifest_path.stat().st_mode & 0o777
+ temporary_path = None
+ try:
+ with tempfile.NamedTemporaryFile(
+ mode="w",
+ encoding="utf-8",
+ dir=manifest_path.parent,
+ prefix=f".{manifest_path.name}.",
+ delete=False,
+ ) as temporary_file:
+ temporary_path = Path(temporary_file.name)
+ temporary_file.write(updated)
+ temporary_file.flush()
+ os.fsync(temporary_file.fileno())
+ temporary_path.chmod(file_mode)
+ os.replace(temporary_path, manifest_path)
+ except Exception:
+ if temporary_path is not None:
+ temporary_path.unlink(missing_ok=True)
+ raise
+
+ new_fields = dict(fields)
+ new_fields["selected_branch"] = STEAM_LOSSLESS_SCALING_BRANCH
+ new_fields["needs_switch"] = new_fields["current_branch"] != STEAM_LOSSLESS_SCALING_BRANCH
+ new_fields["restart_required"] = new_fields["needs_switch"]
+ return self._success_response(
+ dict,
+ "lsfg-vk selected for Lossless Scaling; restart Steam to download it",
+ changed=updated != content,
+ **new_fields,
+ )
+ except Exception as error:
+ return self._error_response(
+ dict,
+ str(error),
+ changed=False,
+ installed=False,
+ manifest_path=None,
+ selected_branch=None,
+ current_branch=None,
+ target_branch=STEAM_LOSSLESS_SCALING_BRANCH,
+ needs_switch=False,
+ restart_required=False,
+ )
diff --git a/py_modules/lsfg_vk/types.py b/py_modules/lsfg_vk/types.py
index 0f0428b..96ce23b 100644
--- a/py_modules/lsfg_vk/types.py
+++ b/py_modules/lsfg_vk/types.py
@@ -42,6 +42,23 @@ class InstallationCheckResponse(TypedDict):
error: Optional[str]
+class SteamBranchStatusResponse(TypedDict):
+ success: bool
+ message: str
+ error: Optional[str]
+ installed: bool
+ manifest_path: Optional[str]
+ selected_branch: Optional[str]
+ current_branch: Optional[str]
+ target_branch: str
+ needs_switch: bool
+ restart_required: bool
+
+
+class SteamBranchOperationResponse(SteamBranchStatusResponse):
+ changed: bool
+
+
class ConfigurationResponse(BaseResponse):
"""Response for configuration operations"""
config: Optional[ConfigurationData]
diff --git a/src/api/lsfgApi.ts b/src/api/lsfgApi.ts
index 68cf6bf..64d43cb 100644
--- a/src/api/lsfgApi.ts
+++ b/src/api/lsfgApi.ts
@@ -16,6 +16,23 @@ export interface InstallationStatus {
error?: string;
}
+export interface SteamBranchStatus {
+ success: boolean;
+ message: string;
+ error?: string;
+ installed: boolean;
+ manifest_path?: string;
+ selected_branch?: string;
+ current_branch?: string;
+ target_branch: string;
+ needs_switch: boolean;
+ restart_required: boolean;
+}
+
+export interface SteamBranchOperationResult extends SteamBranchStatus {
+ changed: boolean;
+}
+
// Use centralized configuration data type
export type LsfgConfig = ConfigurationData;
@@ -112,6 +129,8 @@ 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 getLosslessScalingBranchStatus = callable<[], SteamBranchStatus>("get_lossless_scaling_branch_status");
+export const selectLosslessScalingBranch = callable<[], SteamBranchOperationResult>("select_lossless_scaling_branch");
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 aab2fb8..4e4e33a 100644
--- a/src/components/Content.tsx
+++ b/src/components/Content.tsx
@@ -15,6 +15,7 @@ import { NerdStuffModal } from "./NerdStuffModal";
import { FlatpaksModal } from "./FlatpaksModal";
import { ConfigurationData } from "../config/configSchema";
import t from '../i18n/i18n';
+import { showErrorToast, showSuccessToast } from "../utils/toastUtils";
export function Content() {
const {
@@ -24,6 +25,9 @@ export function Content() {
setInstallationStatus,
losslessScalingInstalled,
losslessScalingStatus,
+ steamBranchStatus,
+ isSwitchingSteamBranch,
+ selectLosslessScalingBranch,
checkInstallation
} = useInstallationStatus();
@@ -67,6 +71,18 @@ export function Content() {
handleUninstall(setIsInstalled, setInstallationStatus, checkInstallation);
};
+ const onSelectLosslessScalingBranch = async () => {
+ const result = await selectLosslessScalingBranch();
+ if (result.success) {
+ showSuccessToast("Steam branch selected", result.message);
+ } else {
+ showErrorToast(
+ "Steam branch selection failed",
+ result.error || "Unable to select the lsfg-vk Steam branch"
+ );
+ }
+ };
+
const handleShowNerdStuff = () => {
showModal(<NerdStuffModal />);
};
@@ -92,6 +108,9 @@ export function Content() {
installationStatus={installationStatus}
losslessScalingInstalled={losslessScalingInstalled}
losslessScalingStatus={losslessScalingStatus}
+ steamBranchStatus={steamBranchStatus}
+ isSwitchingSteamBranch={isSwitchingSteamBranch}
+ onSelectLosslessScalingBranch={onSelectLosslessScalingBranch}
/>
</>
)}
@@ -172,6 +191,9 @@ export function Content() {
installationStatus={installationStatus}
losslessScalingInstalled={losslessScalingInstalled}
losslessScalingStatus={losslessScalingStatus}
+ steamBranchStatus={steamBranchStatus}
+ isSwitchingSteamBranch={isSwitchingSteamBranch}
+ onSelectLosslessScalingBranch={onSelectLosslessScalingBranch}
/>
<InstallationButton
diff --git a/src/components/StatusDisplay.tsx b/src/components/StatusDisplay.tsx
index 31584eb..b6290b0 100644
--- a/src/components/StatusDisplay.tsx
+++ b/src/components/StatusDisplay.tsx
@@ -1,56 +1,95 @@
-import { PanelSectionRow } from "@decky/ui";
+import { ButtonItem, PanelSectionRow } from "@decky/ui";
+import type { SteamBranchStatus } from "../api/lsfgApi";
interface StatusDisplayProps {
isInstalled: boolean;
installationStatus: string;
losslessScalingInstalled: boolean;
losslessScalingStatus: string;
+ steamBranchStatus: SteamBranchStatus | null;
+ isSwitchingSteamBranch: boolean;
+ onSelectLosslessScalingBranch: () => void;
}
export function StatusDisplay({
isInstalled,
installationStatus,
losslessScalingInstalled,
- losslessScalingStatus
+ losslessScalingStatus,
+ steamBranchStatus,
+ isSwitchingSteamBranch,
+ onSelectLosslessScalingBranch
}: StatusDisplayProps) {
return (
- <PanelSectionRow>
- <div style={{ marginBottom: "8px", fontSize: "14px" }}>
- <div
- style={{
- color: losslessScalingInstalled ? "#4CAF50" : "#F44336",
- fontWeight: "600",
- marginBottom: "6px",
- display: "flex",
- alignItems: "center",
- gap: "6px"
- }}
- >
- <span style={{ fontSize: "16px" }}>
- {losslessScalingInstalled ? "✅" : "❌"}
- </span>
- {losslessScalingInstalled ? "Lossless Scaling Installed" : "Lossless Scaling Not Installed"}
- </div>
- {!losslessScalingInstalled && losslessScalingStatus && (
- <div style={{ color: "#B8B8B8", fontSize: "12px", margin: "0 0 6px 22px" }}>
- {losslessScalingStatus}
+ <>
+ <PanelSectionRow>
+ <div style={{ marginBottom: "8px", fontSize: "14px" }}>
+ <div
+ style={{
+ color: losslessScalingInstalled ? "#4CAF50" : "#F44336",
+ fontWeight: "600",
+ marginBottom: "6px",
+ display: "flex",
+ alignItems: "center",
+ gap: "6px"
+ }}
+ >
+ <span style={{ fontSize: "16px" }}>
+ {losslessScalingInstalled ? "✅" : "❌"}
+ </span>
+ {losslessScalingInstalled ? "Lossless Scaling Installed" : "Lossless Scaling Not Installed"}
+ </div>
+ {!losslessScalingInstalled && losslessScalingStatus && (
+ <div style={{ color: "#B8B8B8", fontSize: "12px", margin: "0 0 6px 22px" }}>
+ {losslessScalingStatus}
+ </div>
+ )}
+ <div
+ style={{
+ color: isInstalled ? "#4CAF50" : "#FF9800",
+ fontWeight: "600",
+ display: "flex",
+ alignItems: "center",
+ gap: "6px"
+ }}
+ >
+ <span style={{ fontSize: "16px" }}>
+ {isInstalled ? "✅" : "❌"}
+ </span>
+ {installationStatus}
</div>
- )}
- <div
- style={{
- color: isInstalled ? "#4CAF50" : "#FF9800",
- fontWeight: "600",
- display: "flex",
- alignItems: "center",
- gap: "6px"
- }}
- >
- <span style={{ fontSize: "16px" }}>
- {isInstalled ? "✅" : "❌"}
- </span>
- {installationStatus}
</div>
- </div>
- </PanelSectionRow>
+ </PanelSectionRow>
+
+ {losslessScalingInstalled && steamBranchStatus?.installed && (
+ <PanelSectionRow>
+ <div style={{ width: "100%" }}>
+ <div
+ style={{
+ color: steamBranchStatus.needs_switch ? "#FF9800" : "#4CAF50",
+ fontSize: "12px",
+ margin: "0 0 6px 22px"
+ }}
+ >
+ Steam branch: {steamBranchStatus.current_branch || "public"}
+ {steamBranchStatus.needs_switch && (
+ <div style={{ color: "#B8B8B8", marginTop: "3px" }}>
+ {steamBranchStatus.message}
+ </div>
+ )}
+ </div>
+ {steamBranchStatus.needs_switch && (
+ <ButtonItem
+ layout="below"
+ onClick={onSelectLosslessScalingBranch}
+ disabled={isSwitchingSteamBranch}
+ >
+ {isSwitchingSteamBranch ? "Selecting lsfg-vk..." : "Use lsfg-vk Steam branch"}
+ </ButtonItem>
+ )}
+ </div>
+ </PanelSectionRow>
+ )}
+ </>
);
}
diff --git a/src/hooks/useLsfgHooks.ts b/src/hooks/useLsfgHooks.ts
index 597110e..dfbf2cd 100644
--- a/src/hooks/useLsfgHooks.ts
+++ b/src/hooks/useLsfgHooks.ts
@@ -2,8 +2,12 @@ import { useState, useEffect, useCallback } from "react";
import {
checkLsfgVkInstalled,
getLsfgConfig,
+ getLosslessScalingBranchStatus,
+ selectLosslessScalingBranch,
updateLsfgConfigFromObject,
- type ConfigUpdateResult
+ type ConfigUpdateResult,
+ type SteamBranchOperationResult,
+ type SteamBranchStatus
} from "../api/lsfgApi";
import { ConfigurationData, getDefaults } from "../config/configSchema";
import { showErrorToast, ToastMessages } from "../utils/toastUtils";
@@ -13,9 +17,18 @@ export function useInstallationStatus() {
const [installationStatus, setInstallationStatus] = useState<string>("");
const [losslessScalingInstalled, setLosslessScalingInstalled] = useState<boolean>(false);
const [losslessScalingStatus, setLosslessScalingStatus] = useState<string>("");
+ const [steamBranchStatus, setSteamBranchStatus] = useState<SteamBranchStatus | null>(null);
+ const [isSwitchingSteamBranch, setIsSwitchingSteamBranch] = useState<boolean>(false);
const checkInstallation = async () => {
try {
+ setSteamBranchStatus(await getLosslessScalingBranchStatus());
+ } catch (error) {
+ console.error("Error checking Lossless Scaling Steam branch:", error);
+ setSteamBranchStatus(null);
+ }
+
+ try {
const status = await checkLsfgVkInstalled();
setIsInstalled(status.installed);
setLosslessScalingInstalled(status.lossless_scaling_installed);
@@ -27,6 +40,7 @@ export function useInstallationStatus() {
}
return status.installed;
} catch (error) {
+ setSteamBranchStatus(null);
setLosslessScalingInstalled(false);
setLosslessScalingStatus("Lossless Scaling Not Installed");
setInstallationStatus("lsfg-vk Not Installed");
@@ -34,6 +48,33 @@ export function useInstallationStatus() {
}
};
+ const selectLosslessScalingBranchForUser = async (): Promise<SteamBranchOperationResult> => {
+ setIsSwitchingSteamBranch(true);
+ try {
+ const result = await selectLosslessScalingBranch();
+ setSteamBranchStatus(result);
+ return result;
+ } catch (error) {
+ const result: SteamBranchOperationResult = {
+ success: false,
+ message: "",
+ error: String(error),
+ installed: false,
+ manifest_path: undefined,
+ selected_branch: undefined,
+ current_branch: undefined,
+ target_branch: "lsfg-vk",
+ needs_switch: false,
+ restart_required: false,
+ changed: false
+ };
+ setSteamBranchStatus(result);
+ return result;
+ } finally {
+ setIsSwitchingSteamBranch(false);
+ }
+ };
+
useEffect(() => {
checkInstallation();
}, []);
@@ -45,6 +86,9 @@ export function useInstallationStatus() {
setInstallationStatus,
losslessScalingInstalled,
losslessScalingStatus,
+ steamBranchStatus,
+ isSwitchingSteamBranch,
+ selectLosslessScalingBranch: selectLosslessScalingBranchForUser,
checkInstallation
};
}