chore: release v0.21.3

This commit is contained in:
2026-07-26 16:57:19 +02:00
parent 4fd70f6a9d
commit 91b5af1c7b
46 changed files with 2491 additions and 355 deletions
+31 -6
View File
@@ -73,6 +73,24 @@ function attOptions(model?: string): { v: string; l: string }[] {
return [OFF, { v: '20', l: '20dB' }]; // IC-7300 / IC-705 / IC-7100 / default
}
// bandOfHz names the amateur band a frequency falls in, so the band row can show
// where the rig actually is. The buttons only ever SENT a frequency and carried
// no active state at all, so nothing was highlighted whatever the rig reported.
// Edges are the ITU/IARU band limits, wide enough to cover regional differences —
// out-of-band (transverter IF, general coverage RX) matches nothing, as it should.
function bandOfHz(hz?: number): string {
if (!hz || hz <= 0) return '';
const mhz = hz / 1_000_000;
const bands: [string, number, number][] = [
['160', 1.8, 2.0], ['80', 3.5, 4.0], ['60', 5.25, 5.45], ['40', 7.0, 7.3],
['30', 10.1, 10.15], ['20', 14.0, 14.35], ['17', 18.068, 18.168],
['15', 21.0, 21.45], ['12', 24.89, 24.99], ['10', 28.0, 29.7],
['6', 50.0, 54.0], ['4', 70.0, 70.5], ['2', 144.0, 148.0], ['70', 430.0, 450.0],
];
for (const [name, lo, hi] of bands) if (mhz >= lo && mhz <= hi) return name;
return '';
}
// fmtVFO renders a Hz frequency the way an Icom front panel does:
// MHz "." 3-digit-kHz "." 2-digit-(10 Hz). 21032000 → "21.032.00".
function fmtVFO(hz?: number): string {
@@ -731,12 +749,19 @@ export function IcomPanel({ onReportRST, isNetwork = false }: { onReportRST?: (r
{/* Band buttons + antenna selection. */}
<Card icon={Antenna} title={t('icmp.bandsAntenna')} accent="#0891b2">
<div className="grid grid-cols-5 gap-1.5">
{BANDS.map((b) => (
<button key={b.l} type="button" onClick={() => SetCATFrequency(b.hz).catch(() => {})}
className="px-1 py-1.5 rounded-md text-[11px] font-bold border border-border bg-card text-foreground hover:bg-muted transition-colors">
{b.l}
</button>
))}
{BANDS.map((b) => {
const here = bandOfHz(mainHz) === b.l;
return (
<button key={b.l} type="button" onClick={() => SetCATFrequency(b.hz).catch(() => {})}
title={here ? t('icmp.bandCurrent', { b: b.l }) : undefined}
className={cn('px-1 py-1.5 rounded-md text-[11px] font-bold border transition-colors',
here
? 'border-primary bg-primary text-primary-foreground shadow-[0_0_8px] shadow-primary/40'
: 'border-border bg-card text-foreground hover:bg-muted')}>
{b.l}
</button>
);
})}
</div>
<Row label={t('icmp.antenna')}>
<Segmented value={String(st.antenna)} options={[{ v: '1', l: 'ANT1' }, { v: '2', l: 'ANT2' }]}