feat(flex): the marker moves to a right-click on the chaser button

The transmit row already carries SPLIT, TUNE, MOX, the chaser, its offset
and the TX readout. The marker field was the one control on it that is
set once -- to agree with SDC -- and then never touched again, so it is
summoned by right-clicking the button instead of parked there. Enter
commits, Escape restores. The button's tooltip says so: an unannounced
right-click is not a feature.
This commit is contained in:
2026-08-23 19:08:58 +02:00
parent 32036a93ed
commit 912d727d7a
3 changed files with 30 additions and 21 deletions
+26 -17
View File
@@ -314,6 +314,10 @@ export function FlexPanel({ onCWSpeed, onReportRST }: { onCWSpeed?: (wpm: number
// comma-separated list, and normalising it on every keystroke would eat the
// comma the moment it is typed.
const [rstChaseMarkersText, setRstChaseMarkersText] = useState('599');
// The marker field is summoned by right-clicking the button, not parked on
// the row: it is set once to agree with SDC and then never touched, while the
// row it was sitting in is the busiest in the panel.
const [rstChaseEditing, setRstChaseEditing] = useState(false);
useEffect(() => {
GetFlexRSTChase().then((c: any) => {
if (!c) return;
@@ -675,28 +679,33 @@ export function FlexPanel({ onCWSpeed, onReportRST }: { onCWSpeed?: (wpm: number
chasing — everything else about the feature is configured once. */}
<button type="button" disabled={off}
title={t('flxp.rstChaseHint', { m: rstChase.markers })}
onContextMenu={(e) => { e.preventDefault(); setRstChaseEditing(true); }}
onClick={() => { const on = !rstChase.enabled; setRstChase({ ...rstChase, enabled: on }); SetFlexRSTChaseEnabled(on).catch(() => {}); }}
className={cn('px-3 py-1.5 rounded-lg text-sm font-extrabold tracking-wide border-2 transition-all disabled:opacity-30',
rstChase.enabled ? 'bg-success text-success-foreground border-success shadow-[0_0_12px] shadow-success/50' : 'bg-card text-success border-success hover:bg-success-muted')}>
{rstChase.markers.split(',')[0].trim() || '599'}
</button>
{rstChase.enabled && (
<label className="flex items-center gap-1 text-[11px] text-muted-foreground whitespace-nowrap">
{/* The marker is whatever SDC was told to write — "599", "5NN",
or several. Editable here rather than in a settings page
because it is chosen in the skimmer, and the two have to
agree or nothing ever fires. */}
<input type="text" value={rstChaseMarkersText}
onChange={(e) => setRstChaseMarkersText(e.target.value)}
onBlur={() => {
const v = rstChaseMarkersText.trim() || '599';
setRstChaseMarkersText(v);
const next = { ...rstChase, markers: v };
setRstChase(next); SaveFlexRSTChase(next as any).catch(() => {});
}}
title={t('flxp.rstChaseMarkerHint')}
className="w-20 h-6 rounded border border-input bg-background px-1 text-[11px] font-mono uppercase" />
</label>
{/* The marker is whatever SDC was told to write — "599", "5NN", or
several. It has to agree with the skimmer or nothing ever fires,
so it is edited here rather than in a settings page — but only
when asked for, since it is set once and then left alone. */}
{rstChaseEditing && (
<input type="text" autoFocus value={rstChaseMarkersText}
onChange={(e) => setRstChaseMarkersText(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') (e.target as HTMLInputElement).blur();
if (e.key === 'Escape') { setRstChaseMarkersText(rstChase.markers); setRstChaseEditing(false); }
}}
onBlur={() => {
const v = rstChaseMarkersText.trim() || '599';
setRstChaseMarkersText(v);
setRstChaseEditing(false);
if (v === rstChase.markers) return;
const next = { ...rstChase, markers: v };
setRstChase(next); SaveFlexRSTChase(next as any).catch(() => {});
}}
title={t('flxp.rstChaseMarkerHint')}
className="w-16 h-6 rounded border border-input bg-background px-1 text-[11px] font-mono uppercase" />
)}
{rstChase.enabled && (
<label className="flex items-center gap-1 text-[11px] text-muted-foreground whitespace-nowrap">