feat: update frontend for new upscaler/battery fields
- Replace fsrVersion with upscalerType/upscalerVersion in Preset interface - Update StatsResponse to use upscalerType/upscalerVersion - Replace FSR_OPTIONS with UPSCALER_OPTIONS (FSR, DLSS, XeSS, LSFG, Other) - Update FRAMEGEN_OPTIONS to include LSFG and Other - Update filter state from fsr to upscaler - Update isRawPerformerPreset and getFpsColor to use upscalerType - Update UpscalerBarChart interface and formatCombo function - Update preset card technology tags to display upscaler version
This commit is contained in:
@@ -73,7 +73,8 @@ interface Preset {
|
|||||||
fpsAvg: number | null
|
fpsAvg: number | null
|
||||||
fpsLow: number | null
|
fpsLow: number | null
|
||||||
fpsHigh: number | null
|
fpsHigh: number | null
|
||||||
fsrVersion: string | null
|
upscalerType: string | null
|
||||||
|
upscalerVersion: string | null
|
||||||
frameGenMethod: string | null
|
frameGenMethod: string | null
|
||||||
protonVersion: string | null
|
protonVersion: string | null
|
||||||
osVersion: string | null
|
osVersion: string | null
|
||||||
@@ -89,6 +90,7 @@ interface StatsResponse {
|
|||||||
versionCount: number
|
versionCount: number
|
||||||
}
|
}
|
||||||
isRawPerformer: boolean
|
isRawPerformer: boolean
|
||||||
|
isPoorPerformance: boolean
|
||||||
boxplot: Array<{
|
boxplot: Array<{
|
||||||
hardwareSlug: string
|
hardwareSlug: string
|
||||||
hardwareName: string
|
hardwareName: string
|
||||||
@@ -107,7 +109,8 @@ interface StatsResponse {
|
|||||||
}>
|
}>
|
||||||
}>
|
}>
|
||||||
upscalerStats: Array<{
|
upscalerStats: Array<{
|
||||||
fsrVersion: string
|
upscalerType: string
|
||||||
|
upscalerVersion?: string
|
||||||
frameGenMethod: string
|
frameGenMethod: string
|
||||||
hardwareSlug: string
|
hardwareSlug: string
|
||||||
avgFps: number
|
avgFps: number
|
||||||
@@ -149,8 +152,8 @@ interface Props {
|
|||||||
gameId: string
|
gameId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const FSR_OPTIONS = ["Any", "None", "FSR1", "FSR2", "FSR3"]
|
const UPSCALER_OPTIONS = ["Any", "None", "FSR", "DLSS", "XeSS", "LSFG", "Other"]
|
||||||
const FRAMEGEN_OPTIONS = ["Any", "None", "FSR FG", "DLSS FG"]
|
const FRAMEGEN_OPTIONS = ["Any", "None", "FSR FG", "DLSS FG", "LSFG", "Other"]
|
||||||
|
|
||||||
function formatDate(value: string | null): string {
|
function formatDate(value: string | null): string {
|
||||||
if (!value) return "—"
|
if (!value) return "—"
|
||||||
@@ -161,11 +164,15 @@ function isRawPerformerPreset(preset: Preset): boolean {
|
|||||||
return (
|
return (
|
||||||
preset.fpsAvg !== null &&
|
preset.fpsAvg !== null &&
|
||||||
preset.fpsAvg >= 60 &&
|
preset.fpsAvg >= 60 &&
|
||||||
preset.fsrVersion === "none" &&
|
preset.upscalerType === "none" &&
|
||||||
preset.frameGenMethod === "none"
|
preset.frameGenMethod === "none"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPoorPerformancePreset(preset: Preset): boolean {
|
||||||
|
return preset.fpsAvg !== null && preset.fpsAvg < 30
|
||||||
|
}
|
||||||
|
|
||||||
function getFpsColor(preset: Preset): string {
|
function getFpsColor(preset: Preset): string {
|
||||||
if (preset.fpsAvg === null) return "text-text/60"
|
if (preset.fpsAvg === null) return "text-text/60"
|
||||||
if (isRawPerformerPreset(preset)) return "text-green-400"
|
if (isRawPerformerPreset(preset)) return "text-green-400"
|
||||||
@@ -173,7 +180,7 @@ function getFpsColor(preset: Preset): string {
|
|||||||
if (preset.frameGenMethod === "dlss_fg") return "text-blue-400"
|
if (preset.frameGenMethod === "dlss_fg") return "text-blue-400"
|
||||||
return "text-orange-400"
|
return "text-orange-400"
|
||||||
}
|
}
|
||||||
if (preset.fsrVersion && preset.fsrVersion !== "none")
|
if (preset.upscalerType && preset.upscalerType !== "none")
|
||||||
return "text-orange-400"
|
return "text-orange-400"
|
||||||
return "text-text/60"
|
return "text-text/60"
|
||||||
}
|
}
|
||||||
@@ -192,7 +199,7 @@ export function GamePageClient({
|
|||||||
const [filters, setFilters] = useState({
|
const [filters, setFilters] = useState({
|
||||||
proton: "all",
|
proton: "all",
|
||||||
os: "all",
|
os: "all",
|
||||||
fsr: "all",
|
upscaler: "all",
|
||||||
frameGen: "all",
|
frameGen: "all",
|
||||||
})
|
})
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
@@ -243,7 +250,7 @@ export function GamePageClient({
|
|||||||
const filterUpscaler = (arr: StatsResponse["upscalerStats"]) =>
|
const filterUpscaler = (arr: StatsResponse["upscalerStats"]) =>
|
||||||
arr.filter((item) => {
|
arr.filter((item) => {
|
||||||
if (!deviceSet.has(item.hardwareSlug)) return false
|
if (!deviceSet.has(item.hardwareSlug)) return false
|
||||||
if (filters.fsr !== "all" && item.fsrVersion !== filters.fsr)
|
if (filters.upscaler !== "all" && item.upscalerType !== filters.upscaler)
|
||||||
return false
|
return false
|
||||||
if (
|
if (
|
||||||
filters.frameGen !== "all" &&
|
filters.frameGen !== "all" &&
|
||||||
@@ -282,7 +289,7 @@ export function GamePageClient({
|
|||||||
if (filters.proton !== "all" && p.protonVersion !== filters.proton)
|
if (filters.proton !== "all" && p.protonVersion !== filters.proton)
|
||||||
return false
|
return false
|
||||||
if (filters.os !== "all" && p.osVersion !== filters.os) return false
|
if (filters.os !== "all" && p.osVersion !== filters.os) return false
|
||||||
if (filters.fsr !== "all" && p.fsrVersion !== filters.fsr)
|
if (filters.upscaler !== "all" && p.upscalerType !== filters.upscaler)
|
||||||
return false
|
return false
|
||||||
if (
|
if (
|
||||||
filters.frameGen !== "all" &&
|
filters.frameGen !== "all" &&
|
||||||
@@ -351,6 +358,11 @@ export function GamePageClient({
|
|||||||
Raw Performer
|
Raw Performer
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
{stats?.isPoorPerformance && (
|
||||||
|
<span className='inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-red-500/10 border border-red-500/20 text-red-400 text-[10px] font-semibold'>
|
||||||
|
⚠ Poor Performance
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Subtitle */}
|
{/* Subtitle */}
|
||||||
@@ -636,11 +648,11 @@ export function GamePageClient({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<FilterSelect
|
<FilterSelect
|
||||||
label='FSR Version'
|
label='Upscaler'
|
||||||
value={filters.fsr}
|
value={filters.upscaler}
|
||||||
options={FSR_OPTIONS.map((o) => o.toLowerCase())}
|
options={UPSCALER_OPTIONS.map((o) => o.toLowerCase())}
|
||||||
onChange={(v) =>
|
onChange={(v) =>
|
||||||
setFilters((f) => ({ ...f, fsr: v }))
|
setFilters((f) => ({ ...f, upscaler: v }))
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<FilterSelect
|
<FilterSelect
|
||||||
@@ -829,6 +841,11 @@ export function GamePageClient({
|
|||||||
Raw
|
Raw
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
{isPoorPerformancePreset(preset) && preset.fpsAvg !== null && (
|
||||||
|
<span className='inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded-full bg-red-500/10 border border-red-500/20 text-red-400 text-[9px] font-semibold'>
|
||||||
|
⚠ Slow
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<p className='text-xs text-text/50 mt-0.5'>
|
<p className='text-xs text-text/50 mt-0.5'>
|
||||||
{preset.hardwareName}
|
{preset.hardwareName}
|
||||||
@@ -869,11 +886,12 @@ export function GamePageClient({
|
|||||||
|
|
||||||
{/* Technology tags */}
|
{/* Technology tags */}
|
||||||
<div className='flex flex-wrap items-center gap-1.5'>
|
<div className='flex flex-wrap items-center gap-1.5'>
|
||||||
{preset.fsrVersion &&
|
{preset.upscalerType &&
|
||||||
preset.fsrVersion !==
|
preset.upscalerType !==
|
||||||
"none" && (
|
"none" && (
|
||||||
<span className='px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-500/10 text-purple-400 border border-purple-500/20'>
|
<span className='px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-500/10 text-purple-400 border border-purple-500/20'>
|
||||||
{preset.fsrVersion.toUpperCase()}
|
{preset.upscalerType.toUpperCase()}
|
||||||
|
{preset.upscalerVersion ? ` ${preset.upscalerVersion}` : ""}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{preset.frameGenMethod &&
|
{preset.frameGenMethod &&
|
||||||
|
|||||||
@@ -5,17 +5,28 @@ import { EChartWrapper, CHART_THEME, getDeviceColor } from "./EChartWrapper"
|
|||||||
import type { EChartsOption } from "echarts"
|
import type { EChartsOption } from "echarts"
|
||||||
|
|
||||||
interface UpscalerStat {
|
interface UpscalerStat {
|
||||||
fsrVersion: string
|
upscalerType: string
|
||||||
|
upscalerVersion?: string | null
|
||||||
frameGenMethod: string
|
frameGenMethod: string
|
||||||
hardwareSlug: string
|
hardwareSlug: string
|
||||||
avgFps: number
|
avgFps: number
|
||||||
count: number
|
count: number
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatCombo(fsr: string, fg: string): string {
|
function formatCombo(upscalerType: string, upscalerVersion: string | null | undefined, fg: string): string {
|
||||||
const parts: string[] = []
|
const parts: string[] = []
|
||||||
if (fsr !== "none") parts.push(fsr.toUpperCase())
|
if (upscalerType !== "none") {
|
||||||
if (fg !== "none") parts.push(fg === "fsr_fg" ? "FSR FG" : "DLSS FG")
|
const upscalerLabel = upscalerVersion
|
||||||
|
? `${upscalerType.toUpperCase()} ${upscalerVersion}`
|
||||||
|
: upscalerType.toUpperCase()
|
||||||
|
parts.push(upscalerLabel)
|
||||||
|
}
|
||||||
|
if (fg !== "none") {
|
||||||
|
if (fg === "fsr_fg") parts.push("FSR FG")
|
||||||
|
else if (fg === "dlss_fg") parts.push("DLSS FG")
|
||||||
|
else if (fg === "lsfg") parts.push("LSFG")
|
||||||
|
else parts.push(fg.toUpperCase())
|
||||||
|
}
|
||||||
return parts.length > 0 ? parts.join(" + ") : "Native"
|
return parts.length > 0 ? parts.join(" + ") : "Native"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +40,7 @@ export function UpscalerBarChart({
|
|||||||
const option = useMemo<EChartsOption>(() => {
|
const option = useMemo<EChartsOption>(() => {
|
||||||
const combos = [
|
const combos = [
|
||||||
...new Set(
|
...new Set(
|
||||||
data.map((d) => formatCombo(d.fsrVersion, d.frameGenMethod)),
|
data.map((d) => formatCombo(d.upscalerType, d.upscalerVersion, d.frameGenMethod)),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
const deviceSlugs = [...new Set(data.map((d) => d.hardwareSlug))]
|
const deviceSlugs = [...new Set(data.map((d) => d.hardwareSlug))]
|
||||||
@@ -40,7 +51,7 @@ export function UpscalerBarChart({
|
|||||||
data: combos.map((combo) => {
|
data: combos.map((combo) => {
|
||||||
const match = data.find(
|
const match = data.find(
|
||||||
(d) =>
|
(d) =>
|
||||||
formatCombo(d.fsrVersion, d.frameGenMethod) === combo &&
|
formatCombo(d.upscalerType, d.upscalerVersion, d.frameGenMethod) === combo &&
|
||||||
d.hardwareSlug === slug,
|
d.hardwareSlug === slug,
|
||||||
)
|
)
|
||||||
return match?.avgFps ?? 0
|
return match?.avgFps ?? 0
|
||||||
|
|||||||
Reference in New Issue
Block a user