fix: bug when autocall for cw keyer is on which was
autocalling no matter which macro now only on CQ fix: ESC stop transmission but also autocall
This commit is contained in:
+30
-16
@@ -598,7 +598,7 @@ export default function App() {
|
||||
const [cwStatus, setCwStatus] = useState<{ wpm: number; pitch: number; level: number; active: boolean }>({ wpm: 0, pitch: 0, level: 0, active: false });
|
||||
const cwOn = cwEnabled && mode === 'CW';
|
||||
useEffect(() => {
|
||||
const offT = EventsOn('cw:text', (t: string) => setCwText((s) => (s + t).slice(-2000)));
|
||||
const offT = EventsOn('cw:text', (t: string) => setCwText((s) => (s + t).slice(-200)));
|
||||
const offS = EventsOn('cw:status', (st: any) => setCwStatus(st));
|
||||
const offE = EventsOn('cw:error', (e: string) => { setError(String(e)); setCwEnabled(false); });
|
||||
return () => { offT?.(); offS?.(); offE?.(); };
|
||||
@@ -1476,8 +1476,16 @@ export default function App() {
|
||||
function wkSendMacro(i: number) {
|
||||
const m = wkMacros[i];
|
||||
if (!m) return;
|
||||
if (wkAutoCallRef.current) runAutoCall(i); // loop this macro until a reply / stop
|
||||
else wkSend(m.text);
|
||||
// Auto-call only loops CQ-type macros. Sending any other macro (e.g. a
|
||||
// report once someone answers) sends ONCE and cancels a running loop —
|
||||
// otherwise a report would keep repeating.
|
||||
const isCQ = (m.text || '').toUpperCase().includes('CQ');
|
||||
if (wkAutoCallRef.current && isCQ) {
|
||||
runAutoCall(i); // loop this CQ until a reply is sent / Stop / ESC
|
||||
} else {
|
||||
stopAutoCall();
|
||||
wkSend(m.text);
|
||||
}
|
||||
}
|
||||
wkSendMacroRef.current = wkSendMacro;
|
||||
function wkToggleAutoCall(on: boolean) {
|
||||
@@ -2046,7 +2054,9 @@ export default function App() {
|
||||
return;
|
||||
}
|
||||
const keyerLive = wkActiveRef.current;
|
||||
if (keyerLive) WinkeyerStop().catch(() => {});
|
||||
// ESC aborts the current CW transmission AND the auto-call loop, so it
|
||||
// won't resend after the gap — you must click a CQ macro to restart it.
|
||||
if (keyerLive) { stopAutoCall(); WinkeyerStop().catch(() => {}); }
|
||||
if (!keyerLive || wkEscClearsRef.current) {
|
||||
resetEntry();
|
||||
callsignRef.current?.focus();
|
||||
@@ -3202,21 +3212,25 @@ export default function App() {
|
||||
<span className="shrink-0 font-mono text-[10px] text-muted-foreground tabular-nums">
|
||||
{cwStatus.wpm > 0 ? `${cwStatus.wpm} WPM` : '— WPM'} · {cwStatus.pitch > 0 ? `${cwStatus.pitch} Hz` : '— Hz'}
|
||||
</span>
|
||||
<div className="flex-1 min-w-0 overflow-x-auto whitespace-nowrap font-mono leading-5">
|
||||
{/* Single-line rolling ticker — no scrollbar; newest text stays
|
||||
pinned to the right, older text scrolls off the left. */}
|
||||
<div className="flex-1 min-w-0 overflow-hidden font-mono leading-5">
|
||||
{cwText.trim() === '' ? (
|
||||
<span className="text-muted-foreground italic">listening…</span>
|
||||
) : (
|
||||
cwText.trim().split(/\s+/).map((tok, i) => (
|
||||
<button
|
||||
key={i}
|
||||
type="button"
|
||||
className="mr-1 rounded px-1 hover:bg-emerald-200/70"
|
||||
title="Use as callsign"
|
||||
onClick={() => onCallsignInput(tok, { force: true })}
|
||||
>
|
||||
{tok}
|
||||
</button>
|
||||
))
|
||||
<div className="flex justify-end whitespace-nowrap">
|
||||
{cwText.trim().split(/\s+/).map((tok, i) => (
|
||||
<button
|
||||
key={i}
|
||||
type="button"
|
||||
className="ml-1 shrink-0 rounded px-1 hover:bg-emerald-200/70"
|
||||
title="Use as callsign"
|
||||
onClick={() => onCallsignInput(tok, { force: true })}
|
||||
>
|
||||
{tok}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<button type="button" className="shrink-0 text-muted-foreground hover:text-foreground" title="Clear" onClick={() => setCwText('')}>
|
||||
|
||||
@@ -181,7 +181,7 @@ export function WinkeyerPanel({
|
||||
someone answers. The seconds box is the gap AFTER the message. */}
|
||||
<div className="flex items-center gap-2">
|
||||
<label className="flex items-center gap-1.5 text-xs cursor-pointer select-none"
|
||||
title="After you click a macro (e.g. F1 CQ), resend it on a loop — message, then the gap, then repeat — until a callsign is entered or you press Stop">
|
||||
title="Click a CQ macro (one whose text contains CQ) to resend it on a loop — message, gap, repeat — until you send another macro (e.g. a report), press Stop, or hit ESC. Non-CQ macros send once.">
|
||||
<input type="checkbox" className="accent-primary" checked={autoCall} disabled={!connected}
|
||||
onChange={(e) => onToggleAutoCall(e.target.checked)} />
|
||||
Auto-call
|
||||
@@ -193,7 +193,7 @@ export function WinkeyerPanel({
|
||||
value={autoCallSecs} onChange={(e) => onSetAutoCallSecs(parseInt(e.target.value) || 0)} />
|
||||
<span className="text-[9px] text-muted-foreground">sec</span>
|
||||
</div>
|
||||
{autoCall && <span className="text-[10px] text-amber-600/80">click a macro to loop it</span>}
|
||||
{autoCall && <span className="text-[10px] text-amber-600/80">click a CQ macro to loop it</span>}
|
||||
</div>
|
||||
|
||||
{/* Macro buttons F1… — single-line (F-key + label) to keep the panel short. */}
|
||||
|
||||
Reference in New Issue
Block a user