diff --git a/internal/gui/app.go b/internal/gui/app.go index 5e76be2..c7e26ee 100644 --- a/internal/gui/app.go +++ b/internal/gui/app.go @@ -68,8 +68,8 @@ type Config struct { // for them on the "check:result" event. Mirrors checker.Result but with // Duration converted to milliseconds (int) for the JS side. type CheckResult struct { - ID string `json:"id"` // tcp / greet / auth / connect / udp / stun / api - Status string `json:"status"` // running | passed | failed | skipped + ID string `json:"id"` // tcp / greet / auth / connect / udp / voice-quality / voice-srv / api + Status string `json:"status"` // running | passed | warn | failed | skipped Metric string `json:"metric,omitempty"` Error string `json:"error,omitempty"` Hint string `json:"hint,omitempty"` @@ -136,7 +136,9 @@ func (a *App) RunCheck(cfg Config) { Attempt: r.Attempt, }) switch r.Status { - case checker.StatusPassed: + case checker.StatusPassed, checker.StatusWarn: + // Warn is a "soft pass" — counted as passed for the + // final summary, but the row still surfaces the hint. passed++ case checker.StatusFailed: failed++ diff --git a/internal/gui/frontend/src/components/Classic.jsx b/internal/gui/frontend/src/components/Classic.jsx index fa97bff..c84bf3a 100644 --- a/internal/gui/frontend/src/components/Classic.jsx +++ b/internal/gui/frontend/src/components/Classic.jsx @@ -65,7 +65,7 @@ export function ClassicWindow({ mode = 'dark', initial, onToggleMode }) { const D = useDrover(initial); const [version, setVersion] = React.useState(''); React.useEffect(() => { GoVersion().then(setVersion).catch(() => {}); }, []); - const palette = { pending: t.dimmer, running: t.accent, passed: t.pass, failed: t.danger, skipped: t.skip }; + const palette = { pending: t.dimmer, running: t.accent, passed: t.pass, failed: t.danger, skipped: t.skip, warn: t.warn }; const fontMono = '"JetBrains Mono","SF Mono",ui-monospace,Menlo,Consolas,monospace'; const fontUI = '"Inter","Segoe UI",system-ui,sans-serif'; const isActive = D.phase === 'active'; @@ -288,7 +288,9 @@ function ClassicStatus({ t, D, palette, fontMono }) { > : D.lastSummary?.failed === 0 - ? All checks passed. Ready to start. + ? (D.lastSummary?.warnings > 0 + ? All checks passed (with warnings). + : All checks passed. Ready to start.) : {D.lastSummary?.failed} of {D.tests.length} checks failed. Some features won't work.} {/* tests */} @@ -308,23 +310,26 @@ function ClassicStatus({ t, D, palette, fontMono }) { {test.label} + color: state === 'failed' ? t.danger : state === 'warn' ? t.warn : state === 'skipped' ? t.skip : t.dim }}> {r?.metric || (state === 'running' ? '...' : '')} - {r?.result === 'failed' && ( + {(r?.result === 'failed' || r?.result === 'warn') && ( )} - {r?.result === 'failed' && r.expanded && ( + {(r?.result === 'failed' || r?.result === 'warn') && r.expanded && (