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" mustBeNumeric
style={{ width: "100%", padding: "4px 8px" }} />
/>
</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" mustBeNumeric
style={{ width: "100%", padding: "4px 8px" }} />
/>
</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_..." bIsPassword
style={{ width: "100%", padding: "4px 8px" }} />
/>
</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>
+18 -43
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,46 +142,23 @@ function Content() {
return ( return (
<> <>
{/* ── Tab navigation ──────────────────────────────────────── */} <MainPanel
<PanelSection title="DeckyVault"> recordingState={recordingState}
<PanelSectionRow> session={session}
<ButtonItem recentSessions={recentSessions}
layout="below" error={error}
onClick={() => setActiveTab("main")} settings={settings}
> onStart={handleStart}
{activeTab === "main" ? "▶ Record" : "Record"} onStop={handleStop}
</ButtonItem> onUpdateSession={updateSession}
</PanelSectionRow> onAddToRecent={addToRecent}
<PanelSectionRow> onReset={reset}
<ButtonItem setError={setError}
layout="below" />
onClick={() => setActiveTab("settings")} <SettingsPanel
> settings={settings}
{activeTab === "settings" ? "▶ Settings" : "Settings"} onUpdateSetting={updateSetting}
</ButtonItem> />
</PanelSectionRow>
</PanelSection>
{activeTab === "main" ? (
<MainPanel
recordingState={recordingState}
session={session}
recentSessions={recentSessions}
error={error}
settings={settings}
onStart={handleStart}
onStop={handleStop}
onUpdateSession={updateSession}
onAddToRecent={addToRecent}
onReset={reset}
setError={setError}
/>
) : (
<SettingsPanel
settings={settings}
onUpdateSetting={updateSetting}
/>
)}
</> </>
) )
} }