fix(rotator): put the SP/LP readout inside the compass itself

It went under the Station Control rotator; the compass that wanted it is the
docked one beside the entry strip. Both are the same RotorCompass, so the
readout moves INTO that component: every compass in the app carries it, and no
caller draws its own.

The bezel already showed the short path as a red marker, but a marker is a
direction, not a number — and the numbers in the status bar are 10px, which is
what prompted this.

Clickable only when the caller passed onGoto, since a compass rendered without
one cannot turn anything and a button that does nothing is worse than a label.
This commit is contained in:
2026-08-13 11:45:49 +02:00
parent 700b688fc0
commit 784d809290
7 changed files with 194 additions and 49 deletions
+13 -31
View File
@@ -77,37 +77,19 @@ function RotatorWidget({ hd, refetch, centerLat, centerLon, bearing, t }: Rotato
title={hd.ok ? t('station.online') : t('station.rotatorNoRead')} />
</div>
<div className="p-3 flex gap-4 items-start">
<div className="flex flex-col gap-2">
<RotorCompass
bearing={bearing ?? null}
headings={hd.ok ? [hd.azimuth] : []}
centerLat={centerLat ?? null}
centerLon={centerLon ?? null}
rotorEnabled={hd.ok}
rotors={hd.rotors}
activeRotor={hd.active}
onSelectRotor={(i) => { SetActiveRotor(i).then(refetch).catch((e) => setErr(String(e?.message ?? e))); }}
onGoto={(az) => turn(az)}
/>
{/* Short and long path to the station being worked, repeated here at a
readable size: the same pair sits in the status bar, where it is 10px
and several operators reported not being able to read it.
Clickable, like the ones up there — a heading you can see and not
act on would be a step backwards. */}
<div className="flex gap-1.5 font-mono">
{([['SP', bearing], ['LP', bearing == null ? null : (bearing + 180) % 360]] as const).map(([lbl, az]) => (
<button key={lbl} type="button" disabled={az == null}
onClick={() => az != null && turn(az)}
title={az == null ? '' : t('station.rotateTo', { az: Math.round(az) })}
className={cn('flex-1 rounded-md border py-1 text-xs font-semibold tabular-nums transition-colors',
az == null
? 'border-border text-muted-foreground/50 cursor-not-allowed'
: 'border-info-border text-info-muted-foreground hover:bg-info-muted')}>
{lbl} {az == null ? '—' : `${Math.round(az)}°`}
</button>
))}
</div>
</div>
{/* The SP/LP readout lives INSIDE RotorCompass, so every compass in the
app carries it rather than each caller drawing its own. */}
<RotorCompass
bearing={bearing ?? null}
headings={hd.ok ? [hd.azimuth] : []}
centerLat={centerLat ?? null}
centerLon={centerLon ?? null}
rotorEnabled={hd.ok}
rotors={hd.rotors}
activeRotor={hd.active}
onSelectRotor={(i) => { SetActiveRotor(i).then(refetch).catch((e) => setErr(String(e?.message ?? e))); }}
onGoto={(az) => turn(az)}
/>
<div className="flex-1 min-w-0 space-y-2">
<div className="font-mono">
<span className="text-2xl font-bold tabular-nums">{hd.ok ? `${hd.azimuth}°` : '—'}</span>