fix(autocall): rest in overs, no phantom miss, and a readable auto readout
The rest between two series was two minutes — four overs on FT8, by which time the DX has worked four other callers and half the time has gone. It is now counted in the station's OWN overs and is one by default: seven calls, one over listened through, and it goes again if the station is still there. The deadline lands mid-cycle on purpose, so "sit out one over" means one over rather than depending on a millisecond of clock skew. A period the target was DECODED in is never counted as a miss. A period is judged more than once — decodes arrive in a burst and stragglers follow — and a later judgement holds a partial view of it, not evidence of absence: D2ACE answered in the very period the counter then read as a miss. The readout moved out of the Auto button and beside it. "Auto D2ACE 1/7 ·1/3" read as one number, and the control changed width every period. The callsign is now the biggest thing on the row, the calls and the missed periods each carry a label, the miss count appears only once there is one, and a station being waited for gets its own amber chip.
This commit is contained in:
@@ -1009,22 +1009,48 @@ export function DecodesPanel({ decodes, txMsgs, txState, txStates, spotStatus, r
|
||||
>
|
||||
<Bot className="size-3.5" />
|
||||
{t('dec.autoCall')}
|
||||
{autoCallOn && autoCall?.target && (
|
||||
<span className="font-mono text-xs">
|
||||
{autoCall.target} {autoCall.calls}/{autoCall.max}
|
||||
{autoCall.misses > 0 ? ` ·${autoCall.misses}/${autoCall.max_miss}` : ''}
|
||||
</span>
|
||||
)}
|
||||
{/* Wanted, decoded, and in a QSO with somebody else. Holding fire
|
||||
looks exactly like having nothing to do, and the operator had no
|
||||
way to tell them apart. */}
|
||||
{autoCallOn && !autoCall?.target && autoCall?.waiting && (
|
||||
<span className="font-mono text-xs animate-pulse" title={t('dec.autoWaitTip', { call: autoCall.waiting })}>
|
||||
{autoCall.waiting} ⏳
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
{/* WHAT IT IS DOING, BESIDE THE SWITCH RATHER THAN ON IT.
|
||||
A thing that keys the transmitter must never be a switch with no
|
||||
readout — but the readout was crammed inside the button as
|
||||
"Auto D2ACE 1/7 ·1/3", where the two counters read as one number and
|
||||
the whole control changed width every period. Out here each figure
|
||||
gets a label, and the station being called is the biggest thing on
|
||||
the row. */}
|
||||
{autoCallOn && autoCall?.target && (
|
||||
<span className="h-8 inline-flex items-center gap-2 rounded-lg border border-success/50 bg-success/10 px-2"
|
||||
title={t('dec.autoTargetTip', { call: autoCall.target })}>
|
||||
<span className="font-mono text-sm font-bold text-success">{autoCall.target}</span>
|
||||
<span className="inline-flex items-center gap-1 text-[11px] text-muted-foreground">
|
||||
<span className="uppercase tracking-wide">{t('dec.autoCalls')}</span>
|
||||
<span className="font-mono tabular-nums text-foreground">{autoCall.calls}/{autoCall.max}</span>
|
||||
</span>
|
||||
{/* Only once there is one to report: a zero that is always there is
|
||||
a figure nobody reads, and it was the half of the pair that got
|
||||
mistaken for the call count. */}
|
||||
{autoCall.misses > 0 && (
|
||||
<span className="inline-flex items-center gap-1 text-[11px] text-muted-foreground">
|
||||
<span className="uppercase tracking-wide">{t('dec.autoMisses')}</span>
|
||||
<span className={cn('font-mono tabular-nums',
|
||||
autoCall.misses + 1 >= autoCall.max_miss ? 'text-warning' : 'text-foreground')}>
|
||||
{autoCall.misses}/{autoCall.max_miss}
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
{/* Wanted, decoded, and in a QSO with somebody else. Holding fire looks
|
||||
exactly like having nothing to do, and the operator had no way to
|
||||
tell them apart. */}
|
||||
{autoCallOn && !autoCall?.target && autoCall?.waiting && (
|
||||
<span className="h-8 inline-flex items-center gap-1.5 rounded-lg border border-warning/50 bg-warning/10 px-2 animate-pulse"
|
||||
title={t('dec.autoWaitTip', { call: autoCall.waiting })}>
|
||||
<span className="text-sm">⏳</span>
|
||||
<span className="font-mono text-sm font-bold text-warning">{autoCall.waiting}</span>
|
||||
<span className="text-[11px] uppercase tracking-wide text-muted-foreground">{t('dec.autoWaiting')}</span>
|
||||
</span>
|
||||
)}
|
||||
{/* The chase list. Raw text while typing, committed on blur or Enter:
|
||||
the stored value is upper-cased and trimmed, and binding the box to
|
||||
that makes the space bar look dead — in a field whose whole purpose
|
||||
|
||||
@@ -2106,7 +2106,7 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
|
||||
const [chaseSotaOn, setChaseSotaOn] = useState(() => localStorage.getItem('opslog.chaseSota') !== '0');
|
||||
const [chaseNew, setChaseNew] = useState(false);
|
||||
const [pskTgt, setPskTgt] = useState<any>({ enabled: false, scope: 'target' });
|
||||
const [ac, setAc] = useState<any>({ enabled: false, only: '', attempts: 7, watched_attempts: 15, misses: 3, max_rounds: 3, rest_min: 2, on_screen_only: true });
|
||||
const [ac, setAc] = useState<any>({ enabled: false, only: '', attempts: 7, watched_attempts: 15, misses: 3, max_rounds: 3, rest_periods: 1, on_screen_only: true });
|
||||
// The named contest callsigns. Raw text in state, written on blur: it is a
|
||||
// multi-line list, and normalising it on every keystroke would fight the
|
||||
// Return key — the one key this box is built around.
|
||||
@@ -5566,7 +5566,7 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
|
||||
['watched_attempts', t('ac.watchedAttempts'), 1, 60],
|
||||
['misses', t('ac.misses'), 1, 10],
|
||||
['max_rounds', t('ac.rounds'), 1, 10],
|
||||
['rest_min', t('ac.rest'), 1, 60],
|
||||
['rest_periods', t('ac.rest'), 1, 20],
|
||||
] as [string, string, number, number][]).map(([k, label, min, max]) => (
|
||||
<span key={k} className="inline-flex items-center gap-1.5">
|
||||
<span className="text-xs text-muted-foreground">{label}</span>
|
||||
|
||||
Reference in New Issue
Block a user