chore: release v0.26.3

This commit is contained in:
2026-08-21 23:28:55 +02:00
parent 0cd243fe00
commit d48420485f
31 changed files with 1908 additions and 164 deletions
+25 -2
View File
@@ -22,7 +22,7 @@ import {
GetSecretStatus, UnlockSecrets,
RotatorGoTo, RotatorStop, SetActiveRotor,
GetDBConnectionInfo, GetLogbookRevision,
GetUltrabeamStatus, SetUltrabeamDirection, UILog,
GetUltrabeamStatus, SetUltrabeamDirection, UILog, FlexZoomForSpot,
GetAntGeniusStatus, GetAntGeniusSettings, AntGeniusActivate,
GetTunerGeniusStatus, GetTunerGeniusSettings, TunerGeniusAutotune, TunerGeniusSetBypass, TunerGeniusSetOperate, TunerGeniusActivate,
GetScpStatus, ScpLookup,
@@ -1690,7 +1690,7 @@ export default function App() {
const [clusterLockMode, setClusterLockMode] = useState(() => lsBool('opslog.clusterLockMode', false));
// Status filter chips. Empty set = show every status (including
// already-worked). Otherwise only matching spots pass.
type SpotStatusKey = 'new' | 'new-band' | 'new-mode' | 'new-slot' | 'worked';
type SpotStatusKey = 'new' | 'new-band-mode' | 'new-band' | 'new-mode' | 'new-slot' | 'worked';
// What the cluster can be FILTERED on. A superset of the entity status: a new
// county or a new park is not a DXCC state, it is another dimension of the
// same spot — which is why the grid shows them as separate badges. Filtering
@@ -3059,6 +3059,10 @@ export default function App() {
}
if (s.band) setBand(s.band);
if (catState.connected) tuneRigCAT(s.freq_hz, m);
// The panadapter width follows the MODE of the spot, when the option is on.
// AFTER the tune, deliberately: a view change must never delay the frequency
// change the operator is waiting for. A no-op on any backend but a Flex.
FlexZoomForSpot(m ?? '', s.freq_hz ?? 0).catch(() => {});
if (m) applyModeFromSpot(m);
onCallsignInput(s.dx_call, { force: true });
applySpotPOTA((s as any).pota_ref);
@@ -5676,6 +5680,20 @@ export default function App() {
>
{clusterLockBand ? <Lock className="size-2.5" /> : <Unlock className="size-2.5" />} {band}
</button>
{/* "My bands" in one click.
No selection means EVERY band, which is what an operator wants
the first time and never again: an RBN feed carries 4 m and
70 cm, and the list above can only offer the bands you have
configured so a band you do not own could not be unticked,
because it was never there to tick. Selecting your own list
makes the filter finite, and the spot goes. */}
{clusterBands.size !== bands.length && (
<button type="button"
onClick={() => setClusterBands(new Set(bands))}
title={t('clu.myBandsTitle')}
className="text-[10px] text-muted-foreground hover:text-foreground underline">{t('clu.myBands')}</button>
)}
{clusterBands.size > 0 && (
<button type="button" onClick={() => setClusterBands(new Set())} className="text-[10px] text-muted-foreground hover:text-foreground underline">{t('clu.clear')}</button>
)}
@@ -5687,6 +5705,9 @@ export default function App() {
<div className="flex flex-wrap gap-1">
{([
{ k: 'new' as SpotFilterKey, label: 'NEW', cls: 'bg-danger-muted text-danger-muted-foreground border-danger-border' },
// NEW BAND+MODE sits between NEW and NEW BAND, which is where it
// ranks: the entity is worked, but neither this band nor this mode.
{ k: 'new-band-mode' as SpotFilterKey, label: 'NEW B+M', cls: 'bg-danger-muted text-danger-muted-foreground border-danger-border' },
{ k: 'new-band' as SpotFilterKey, label: 'NEW BAND', cls: 'bg-warning-muted text-warning-muted-foreground border-warning-border' },
{ k: 'new-mode' as SpotFilterKey, label: 'NEW MODE', cls: 'bg-caution-muted text-caution-muted-foreground border-caution-border' },
{ k: 'new-slot' as SpotFilterKey, label: 'NEW SLOT', cls: 'bg-caution-muted text-caution-muted-foreground border-caution-border' },
@@ -7940,6 +7961,8 @@ export default function App() {
// place a band map happens to be drawn.
fitToBand={bandMapFit}
onToggleFit={toggleBandMapFit}
hideDigital={bandMapHideFt}
onToggleHideDigital={toggleBandMapHideFt}
keyNav
/>
</div>