fix(plugin): merge tabs into single panel, use TextField for controller input

This commit is contained in:
2026-06-28 17:29:22 +08:00
parent 5a6211ebea
commit 2168d31052
3 changed files with 65 additions and 108 deletions
@@ -3,8 +3,8 @@ import {
ButtonItem, ButtonItem,
PanelSection, PanelSection,
PanelSectionRow, PanelSectionRow,
Field,
DropdownItem, DropdownItem,
TextField,
staticClasses, staticClasses,
} from "@decky/ui" } from "@decky/ui"
import { import {
@@ -138,15 +138,12 @@ export default function SessionForm({
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
<Field label="Upscaler Version" bottomSeparator="none"> <TextField
<input label="Upscaler Version"
type="text"
value={session.upscalerVersion} value={session.upscalerVersion}
onChange={(e) => onUpdateSession({ upscalerVersion: e.target.value })} onChange={(e) => onUpdateSession({ upscalerVersion: e.target.value })}
placeholder="e.g. 2.4" placeholder="e.g. 2.4"
style={{ width: "100%", padding: "4px 8px" }}
/> />
</Field>
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
@@ -171,39 +168,32 @@ export default function SessionForm({
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
<Field label="Load Time - SSD (seconds)" bottomSeparator="none"> <TextField
<input label="Load Time - SSD (seconds)"
type="number"
value={session.loadTimeSsd} value={session.loadTimeSsd}
onChange={(e) => onUpdateSession({ loadTimeSsd: e.target.value })} onChange={(e) => onUpdateSession({ loadTimeSsd: e.target.value })}
placeholder="e.g. 12.5" placeholder="e.g. 12.5"
style={{ width: "100%", padding: "4px 8px" }} mustBeNumeric
/> />
</Field>
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
<Field label="Load Time - SD Card (seconds)" bottomSeparator="none"> <TextField
<input label="Load Time - SD Card (seconds)"
type="number"
value={session.loadTimeSd} value={session.loadTimeSd}
onChange={(e) => onUpdateSession({ loadTimeSd: e.target.value })} onChange={(e) => onUpdateSession({ loadTimeSd: e.target.value })}
placeholder="e.g. 25.0" placeholder="e.g. 25.0"
style={{ width: "100%", padding: "4px 8px" }} mustBeNumeric
/> />
</Field>
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
<Field label="Launch Options" bottomSeparator="none"> <TextField
<input label="Launch Options"
type="text"
value={session.launchOptions} value={session.launchOptions}
onChange={(e) => onUpdateSession({ launchOptions: e.target.value })} onChange={(e) => onUpdateSession({ launchOptions: e.target.value })}
placeholder="e.g. mangohud %command%" placeholder="e.g. mangohud %command%"
style={{ width: "100%", padding: "4px 8px" }}
/> />
</Field>
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
@@ -3,8 +3,8 @@ import {
ButtonItem, ButtonItem,
PanelSection, PanelSection,
PanelSectionRow, PanelSectionRow,
Field,
DropdownItem, DropdownItem,
TextField,
staticClasses, staticClasses,
} from "@decky/ui" } from "@decky/ui"
import { import {
@@ -83,15 +83,13 @@ export default function SettingsPanel({
{/* ── API Key ─────────────────────────────────────────────── */} {/* ── API Key ─────────────────────────────────────────────── */}
<PanelSection title="DeckyVault Account"> <PanelSection title="DeckyVault Account">
<PanelSectionRow> <PanelSectionRow>
<Field label="API Key" bottomSeparator="none"> <TextField
<input label="API Key"
type="password"
value={settings.apiKey} value={settings.apiKey}
onChange={(e) => onUpdateSetting("apiKey", e.target.value)} onChange={(e) => onUpdateSetting("apiKey", e.target.value)}
placeholder="dv_..." placeholder="dv_..."
style={{ width: "100%", padding: "4px 8px" }} bIsPassword
/> />
</Field>
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
@@ -127,27 +125,21 @@ export default function SettingsPanel({
{/* ── Export Path ─────────────────────────────────────────── */} {/* ── Export Path ─────────────────────────────────────────── */}
<PanelSection title="Export"> <PanelSection title="Export">
<PanelSectionRow> <PanelSectionRow>
<Field label="Export Path" bottomSeparator="none"> <TextField
<input label="Export Path"
type="text"
value={settings.exportPath} value={settings.exportPath}
onChange={(e) => onUpdateSetting("exportPath", e.target.value)} onChange={(e) => onUpdateSetting("exportPath", e.target.value)}
placeholder="/home/deck/Downloads" placeholder="/home/deck/Downloads"
style={{ width: "100%", padding: "4px 8px" }}
/> />
</Field>
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
<Field label="Server URL" bottomSeparator="none"> <TextField
<input label="Server URL"
type="text"
value={settings.baseUrl} value={settings.baseUrl}
onChange={(e) => onUpdateSetting("baseUrl", e.target.value)} onChange={(e) => onUpdateSetting("baseUrl", e.target.value)}
placeholder="https://deckyvault.xyz" placeholder="https://deckyvault.xyz"
style={{ width: "100%", padding: "4px 8px" }}
/> />
</Field>
</PanelSectionRow> </PanelSectionRow>
<PanelSectionRow> <PanelSectionRow>
+1 -26
View File
@@ -1,8 +1,7 @@
import { useState, useEffect, useRef } from "react" import { useEffect, useRef } from "react"
import { import {
PanelSection, PanelSection,
PanelSectionRow, PanelSectionRow,
ButtonItem,
staticClasses, staticClasses,
} from "@decky/ui" } from "@decky/ui"
import { import {
@@ -37,7 +36,6 @@ function Content() {
onGameStart, onGameStart,
onGameStop, onGameStop,
} = useSession() } = useSession()
const [activeTab, setActiveTab] = useState<"main" | "settings">("main")
const gameStartedUnregRef = useRef<{ unregister: () => void } | null>(null) const gameStartedUnregRef = useRef<{ unregister: () => void } | null>(null)
const gameStoppedUnregRef = useRef<{ unregister: () => void } | null>(null) const gameStoppedUnregRef = useRef<{ unregister: () => void } | null>(null)
@@ -144,27 +142,6 @@ function Content() {
return ( return (
<> <>
{/* ── Tab navigation ──────────────────────────────────────── */}
<PanelSection title="DeckyVault">
<PanelSectionRow>
<ButtonItem
layout="below"
onClick={() => setActiveTab("main")}
>
{activeTab === "main" ? "▶ Record" : "Record"}
</ButtonItem>
</PanelSectionRow>
<PanelSectionRow>
<ButtonItem
layout="below"
onClick={() => setActiveTab("settings")}
>
{activeTab === "settings" ? "▶ Settings" : "Settings"}
</ButtonItem>
</PanelSectionRow>
</PanelSection>
{activeTab === "main" ? (
<MainPanel <MainPanel
recordingState={recordingState} recordingState={recordingState}
session={session} session={session}
@@ -178,12 +155,10 @@ function Content() {
onReset={reset} onReset={reset}
setError={setError} setError={setError}
/> />
) : (
<SettingsPanel <SettingsPanel
settings={settings} settings={settings}
onUpdateSetting={updateSetting} onUpdateSetting={updateSetting}
/> />
)}
</> </>
) )
} }