feat(bandopen): a blinking badge that lasts as long as the opening does
The only sign of a detection was a toast. It is gone in seconds, and an operator who was tuning at that moment had no way back to it — for an event that lasts hours and happens a handful of times a season, that is the wrong shape entirely. The badge sits at the right-hand end of the status bar, before the clock: an opening is a state of the WORLD, not of this station, so it belongs with the time and the logbook rather than among the rig and amplifier chips. Knowing when to go out was the real work. Nothing announces that an opening ended, and the detector deliberately says nothing more about a band for 45 minutes after announcing it — right for a message, useless for a badge. So it is inferred: every qualifying spot on that band pushes a deadline out, and when they stop arriving the badge fades by itself. Fifteen minutes, comfortably more than the detector's own twelve-minute window, so a quiet couple of minutes mid-opening does not blink it off and on again. Gated on the same distance floor the detector uses. Without that, a band busy with short-range tropo would hold an Es badge lit indefinitely on spots the detector itself had refused.
This commit is contained in:
+37
-1
@@ -51,7 +51,7 @@ import {
|
||||
ReportLiveActivity, LiveLastQSOAgeSec,
|
||||
GetAmpStatuses, AmpOperate,
|
||||
GetFlexState, FlexAmpOperate,
|
||||
GetPSKReporterStatus,
|
||||
GetPSKReporterStatus, GetLiveOpenings,
|
||||
} from '../wailsjs/go/main/App';
|
||||
import { Combobox } from '@/components/ui/combobox';
|
||||
import { applyAwardRefs } from '@/lib/awardRefs';
|
||||
@@ -1710,6 +1710,17 @@ export default function App() {
|
||||
const [showSettings, setShowSettings] = useState(false);
|
||||
// Re-read the "beam on map" toggle when Preferences closes (it's edited there).
|
||||
useEffect(() => { if (!showSettings) setShowBeamOnMap(localStorage.getItem('opslog.showBeamOnMap') !== '0'); }, [showSettings]);
|
||||
// Openings under way, for the blinking status-bar badge. Polled rather than
|
||||
// event-driven: the badge also has to go OUT when a band goes quiet, and
|
||||
// nothing emits an event for something that stopped happening.
|
||||
const [liveOpenings, setLiveOpenings] = useState<any[]>([]);
|
||||
useEffect(() => {
|
||||
const load = () => { GetLiveOpenings().then((v: any) => setLiveOpenings(v ?? [])).catch(() => {}); };
|
||||
load();
|
||||
const t = window.setInterval(load, 20000);
|
||||
return () => window.clearInterval(t);
|
||||
}, []);
|
||||
|
||||
// PSK Reporter feed, for the status-bar chip. Polled slowly: the chip only
|
||||
// says up or down, and the count behind it is a tooltip.
|
||||
const [pskr, setPskr] = useState<any>(null);
|
||||
@@ -6942,6 +6953,31 @@ export default function App() {
|
||||
{/* UTC clock — moved out of the header, where it competed with the
|
||||
frequency for the eye. It belongs with the other passive
|
||||
indicators. */}
|
||||
{/* Openings under way. Right-hand end, before the clock, because it is
|
||||
a state of the world rather than a state of this station — the
|
||||
same side as the time and the logbook.
|
||||
|
||||
It BLINKS and it stays. The toast that announces an opening is
|
||||
gone in seconds, and an operator who was tuning at that moment
|
||||
had no way back to it; a band opening lasts hours and deserves
|
||||
something that lasts with it. It goes out by itself when the
|
||||
spots stop arriving. */}
|
||||
{liveOpenings.map((o: any) => (
|
||||
<button
|
||||
key={o.band}
|
||||
type="button"
|
||||
onClick={() => { setActiveTab('bandmap'); }}
|
||||
title={t('bo.liveTip', {
|
||||
band: String(o.band).toUpperCase(), n: o.calls, km: o.median_km,
|
||||
sector: o.sector ?? '', season: o.in_season ? '' : ' — ' + t('bmp.openUnusual'),
|
||||
})}
|
||||
className="inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 text-[11px] font-bold uppercase tracking-wider shrink-0
|
||||
border-warning-border bg-warning-muted text-warning-muted-foreground hover:bg-warning-muted/70 animate-pulse"
|
||||
>
|
||||
<Radio className="size-3" />
|
||||
{String(o.band).toUpperCase()} {t('bo.open')}
|
||||
</button>
|
||||
))}
|
||||
<span className="inline-flex items-center gap-1 font-mono text-[11px] text-muted-foreground shrink-0" title="UTC">
|
||||
<Clock className="size-3" />
|
||||
{utcNow}<span className="text-[9px]">Z</span>
|
||||
|
||||
Reference in New Issue
Block a user