diff --git a/frontend/src/components/YaesuPanel.tsx b/frontend/src/components/YaesuPanel.tsx index 612eadd..800da89 100644 --- a/frontend/src/components/YaesuPanel.tsx +++ b/frontend/src/components/YaesuPanel.tsx @@ -105,15 +105,31 @@ function bandOfHz(hz?: number): string { // falls; the front panel puts it at roughly half travel, which is the 50 used // here. That figure is a HYPOTHESIS — if reports come out consistently one S // unit off on a radio, this is the number to correct, not the RST helper. +const S9_PCT = 50; // where S9 falls on the 0-100 reading (see above) +const DB_PER_PCT = 60 / 50; // above S9 the scale runs to roughly +60 dB + function sParts(v: number): { s: number; over: number; label: string } { - if (v >= 50) { - const over = Math.max(0, Math.round((v - 50) * 60 / 50)); + if (v >= S9_PCT) { + const over = Math.max(0, Math.round((v - S9_PCT) * DB_PER_PCT)); return { s: 9, over, label: over > 0 ? `S9+${over}` : 'S9' }; } - const s = Math.max(0, Math.min(9, Math.round(v / 5.5))); + const s = Math.max(0, Math.min(9, Math.round(v / (S9_PCT / 9)))); return { s, over: 0, label: `S${s}` }; } +// Segment colour, the way a radio's own meter is printed: green up to S9, amber +// through the S9+ range, red once the signal is strong enough to be reported as +// 59+20 or more. Derived from the SAME S9 point as the label, so the colour +// change always lands exactly where the numbers say it should — if the S9 point +// is ever corrected, the colours follow on their own. +const RED_OVER_DB = 20; +function sSegColor(frac: number): string { + const pct = frac * 100; + if (pct < S9_PCT) return '#16a34a'; + if ((pct - S9_PCT) * DB_PER_PCT < RED_OVER_DB) return '#f59e0b'; + return '#dc2626'; +} + function Slider({ value, onChange, disabled, accent = 'var(--primary)', min = 0, max = 100 }: { value: number; onChange: (v: number) => void; disabled?: boolean; accent?: string; min?: number; max?: number; }) { @@ -311,7 +327,7 @@ export function YaesuPanel({ onReportRST }: { onReportRST?: (rst: string) => voi consoles read alike instead of each having its own instrument style. */}
- { const sp = sParts(view.s_meter); onReportRST(sMeterRST(sp.s, sp.over, view.mode)); } : undefined} title={onReportRST ? t('yaesu.sToRst') : undefined} />