import { useEffect } from "react"
import {
PanelSection,
PanelSectionRow,
staticClasses,
} from "@decky/ui"
import {
definePlugin,
routerHook,
} from "@decky/api"
import { FaChartLine } from "react-icons/fa"
import MainPanel from "./components/main-panel"
import { registerLibraryAppPatch, setLibraryAppPanelProps } from "./patches/LibraryApp"
import { useSettings, useSession, useGameDetection } from "./lib/store"
import {
readAndParseMangohudLog,
clearMangohudLog,
deleteLogFile,
findMangohudLog,
startMangohudLogging,
stopMangohudLogging,
getHardwareInfo,
getOsVersion,
getProtonVersion,
getLaunchOptions,
} from "./lib/api"
function Content() {
const { settings, updateSetting, loaded } = useSettings()
// keep the library panel's props in sync with settings
useEffect(() => {
setLibraryAppPanelProps({ hardwareSlug: settings.hardwareSlug, baseUrl: settings.baseUrl })
}, [settings.hardwareSlug, settings.baseUrl])
const {
recordingState,
session,
recentSessions,
error,
setError,
startRecording,
stopRecording,
updateSession,
addToRecent,
reset,
onGameStart,
onGameStop,
setGameName,
setLastLogPath,
} = useSession()
// ── Game detection via polling ────────────────────────────────
useGameDetection(setGameName, recordingState)
// ── Handle start recording ────────────────────────────────────
async function handleStart() {
// Clear the previous session's specific log if we know it; else safe-clear.
const prev = session.lastLogPath
if (prev) {
await deleteLogFile(prev)
} else {
await clearMangohudLog()
}
// Fire-and-forget: try to start MangoHud logging (retries until game launches)
startMangohudLogging()
startRecording()
}
// ── Handle stop recording: parse log + read system info ────────
async function handleStop() {
try {
// Try to stop MangoHud logging (best-effort, may fail if game already closed)
await stopMangohudLogging()
stopRecording()
// Find the most recent MangoHud log, parse it, remember its path
const logPath = await findMangohudLog()
const logResult = await readAndParseMangohudLog(logPath.path ?? undefined)
if (logResult.error) {
setError(logResult.error)
setLastLogPath(null)
return
}
setLastLogPath(logPath.path ?? null)
// Read system info in parallel
const [hwInfo, osVersion] = await Promise.all([
getHardwareInfo(),
getOsVersion(),
])
// Read Proton version + launch options if we have an app ID
let protonVersion = ""
let launchOptions = ""
const currentAppId = session.appId
if (currentAppId) {
try {
const [pv, lo] = await Promise.all([
getProtonVersion(currentAppId),
getLaunchOptions(currentAppId),
])
protonVersion = pv
launchOptions = lo
} catch {
// Non-critical, continue without
}
}
// Use settings hardware override if set, otherwise auto-detected
const hardwareSlug = settings.hardwareSlug || hwInfo.slug
updateSession({
fpsAvg: logResult.fpsAvg ?? null,
fpsLow: logResult.fpsLow ?? null,
fpsHigh: logResult.fpsHigh ?? null,
fpsOnePercentLow: logResult.fpsOnePercentLow ?? null,
tdpWatts: logResult.tdpWatts ?? null,
hardwareSlug,
hardwareName: hwInfo.name,
osVersion,
protonVersion,
launchOptions,
})
} catch (e) {
console.error("[DeckyVault] Error stopping recording:", e)
setError("Failed to process recording. Check the MangoHud log.")
}
}
if (!loaded) {
return (