From b108f0436bad09070efd942b131ef3ca6de7618e Mon Sep 17 00:00:00 2001 From: Adrian Bonpin Date: Mon, 13 Jul 2026 06:18:21 +0800 Subject: [PATCH] =?UTF-8?q?fix(plugin):=20minimal=20library=20panel=20?= =?UTF-8?q?=E2=80=94=20single=20stats=20row,=20no=20header?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/LibraryAppPanel.tsx | 170 +++++------------- 1 file changed, 40 insertions(+), 130 deletions(-) diff --git a/plugins/decky-vault/src/components/LibraryAppPanel.tsx b/plugins/decky-vault/src/components/LibraryAppPanel.tsx index 74e98be..abe32a4 100644 --- a/plugins/decky-vault/src/components/LibraryAppPanel.tsx +++ b/plugins/decky-vault/src/components/LibraryAppPanel.tsx @@ -1,13 +1,11 @@ import { useEffect, useState, useRef } from "react" -import { PanelSection, PanelSectionRow, DropdownItem, staticClasses } from "@decky/ui" -import { FaCheck, FaTimes, FaChartLine } from "react-icons/fa" +import { PanelSectionRow, DropdownItem, staticClasses } from "@decky/ui" import { fetchPluginGame, fetchPluginDevices, setPluginApiBaseUrl, type PluginGameResponse, type PluginDeviceRow, - type PluginEntry, } from "../lib/plugin-api" interface Props { @@ -17,40 +15,6 @@ interface Props { baseUrl: string } -function EntryCard({ e }: { e: PluginEntry }) { - const [expanded, setExpanded] = useState(false) - const settingsCount = Array.isArray(e.settingsJson) - ? (e.settingsJson as Array<{ settings: unknown[] }>).reduce((s, c) => s + (c.settings?.length ?? 0), 0) - : 0 - const label = e.isPinned ? "Pinned" : e.upvotes > 0 ? `${e.upvotes}👍` : "Recent" - return ( - -
setExpanded((v) => !v)} - style={{ padding: "8px 10px", borderRadius: "8px", background: "rgba(255,255,255,0.06)", border: "1px solid rgba(255,255,255,0.10)", cursor: "pointer" }} - > -
- {e.fpsAvg} FPS avg - {label} -
-
- {e.fpsLow ?? "—"} low · {e.fpsOnePercentLow ?? "—"} 1% · {e.fpsHigh ?? "—"} high - {e.tdpWatts ? ` · ${e.tdpWatts}W` : ""} - {e.upscalerType && e.upscalerType !== "none" ? ` · ${e.upscalerType}` : ""} - {e.protonVersion ? ` · Proton ${e.protonVersion}` : ""} -
- {expanded && ( -
-
By {e.userName ?? "unknown"} · {new Date(e.createdAt).toLocaleDateString()}
-
{settingsCount} settings
- {e.osVersion &&
OS: {e.osVersion}
} -
- )} -
-
- ) -} - export default function LibraryAppPanel({ appId, title, hardwareSlug, baseUrl }: Props) { const [data, setData] = useState(null) const [devices, setDevices] = useState([]) @@ -68,16 +32,12 @@ export default function LibraryAppPanel({ appId, title, hardwareSlug, baseUrl }: try { const d = await fetchPluginGame(appId, device || null, 3) if (cancelled || id !== reqIdRef.current) return - if (d.error && !d.game) { - setFetchError(d.error) - } else { - setFetchError("") - } + setFetchError(d.error && !d.game ? d.error : "") setData(d) setLoading(false) const devs = await fetchPluginDevices(appId) if (!cancelled && id === reqIdRef.current) setDevices(devs) - } catch (e) { + } catch { if (!cancelled && id === reqIdRef.current) { setData(null) setFetchError("Request failed") @@ -89,16 +49,6 @@ export default function LibraryAppPanel({ appId, title, hardwareSlug, baseUrl }: return () => { cancelled = true } }, [appId, device, baseUrl]) - if (loading) { - return ( - - -
Loading DeckyVault…
-
-
- ) - } - const deviceOptions = [ { label: "All devices", data: "" }, ...(hardwareSlug ? [{ label: `Your device (${hardwareSlug})`, data: hardwareSlug }] : []), @@ -107,103 +57,63 @@ export default function LibraryAppPanel({ appId, title, hardwareSlug, baseUrl }: .map((d) => ({ label: `${d.name} (${d.count})`, data: d.slug })), ] + // Minimal single-row stats — no header, no entry cards + if (loading) { + return ( + +
+ DeckyVault loading… +
+
+ ) + } + if (fetchError) { return ( - - -
- Could not load DeckyVault data: {fetchError} -
-
-
+ +
+ DeckyVault: {fetchError} +
+
) } if (!data || !data.game) { return ( - - -
- Not in DeckyVault yet. Open {title} on{" "} - deckyvault.xyz to add it. -
-
-
+ +
+ Not on DeckyVault — add it +
+
) } return ( - + <> -
- In DeckyVault +
+ {device && data.estFps ? ( + <> + DeckyVault est FPS: + {data.estFps.avg} + avg · {data.estFps.low ?? "—"} low · {data.estFps.high ?? "—"} high · {data.estFps.count} entries + + ) : ( + + {device + ? "No entries for this device yet" + : "Select a device to see estimated FPS"} + + )}
- - {/* Est FPS — hidden when "All devices" selected to avoid mixing hardware */} - {device ? ( - <> - -
- Est FPS -
-
- {data.estFps ? ( - -
- {data.estFps.avg} avg · {data.estFps.low ?? "—"} low · {data.estFps.onePct ?? "—"} 1% · {data.estFps.high ?? "—"} high - · {data.estFps.count} entries -
-
- ) : ( - -
- No entries for this device yet — be the first: open the DeckyVault plugin and record. -
-
- )} - - ) : ( - -
- Select a device to see estimated FPS. -
-
- )} - - {/* Device switcher */} setDevice(opt.data as string)} /> - - {/* Top entries */} - {data.topEntries.length > 0 && ( - <> - -
- Top entries -
-
- {data.topEntries.map((e) => )} - - )} - - {/* Recent entries */} - {data.recentEntries.length > 0 && ( - <> - -
- Recent entries -
-
- {data.recentEntries.map((e) => )} - - )} - + ) } \ No newline at end of file