fix(ui): one section name, a chosen digital row, no MQTT chip

Three things reported together.

Preferences said the section name twice: a small line above every panel
repeated the heading right underneath it — "GENERAL" over "General" —
while the sidebar next to them already shows which section is open,
highlighted. Two lines and a highlight for one fact; the small line goes.

The band matrix opens on the digital row the operator chooses. Its
digital row has always rotated — DIGI, then each digital mode in their
own list — but it always STARTED on DIGI, so somebody who only works FT8
clicked through to their own mode on every callsign. Settings ▸ General
now says where the rotation starts, and the dropdown offers exactly the
modes the matrix rotates through (the phone-mode rule is now shared
rather than copied, so the two cannot drift). DIGI stays the default: it
is the right answer for anyone working several digital modes.

And the MQTT chip is gone from the status bar. That is the name of a
message protocol, not of anything an operator has — a chip in the status
bar has to say what it is about, and this one told nobody anything. What
it carried is shown in the Chase New panel, which is the place that uses
it; its poller went with it.
This commit is contained in:
2026-09-08 00:10:06 +02:00
parent 5b7469ae44
commit cdd91ab7e6
6 changed files with 67 additions and 40 deletions
+34 -4
View File
@@ -95,6 +95,7 @@ import { AppearancePanel } from '@/components/AppearancePanel';
import { UDPIntegrationsPanel } from '@/components/UDPIntegrationsPanel';
import { loadClusterMacros, saveClusterMacros, type ClusterMacro } from '@/lib/clusterMacros';
import { CLUSTER_PRESETS } from '@/lib/clusterPresets';
import { MATRIX_DIGI_KEY, PHONE_MODES as MATRIX_PHONE_MODES } from '@/components/BandSlotGrid';
type LookupSettings = LookupSettingsForm;
type StationSettings = StationSettingsForm;
@@ -2007,6 +2008,17 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
const [startEqEnd, setStartEqEnd] = useState(() => localStorage.getItem('opslog.startEqualsEnd') === '1');
const [lookupOnBlur, setLookupOnBlur] = useState(() => localStorage.getItem('opslog.lookupOnBlur') === '1');
const [groupDigital, setGroupDigital] = useState(() => localStorage.getItem('opslog.groupDigitalSlots') === '1');
// The digital row the band matrix opens on: '' = DIG, the group of them all.
const [matrixDigi, setMatrixDigi] = useState(() => localStorage.getItem(MATRIX_DIGI_KEY) || '');
// The operator's own digital modes, which is what the matrix rotates through
// — the same rule it uses: everything in their mode list that is neither CW
// nor a phone mode.
const digitalModeNames = useMemo(
() => (lists.modes ?? [])
.map((m: any) => String(m?.name ?? '').toUpperCase().trim())
.filter((m) => m && m !== 'CW' && !MATRIX_PHONE_MODES.has(m)),
[lists.modes],
);
const [milesUnit, setMilesUnit] = useState(() => localStorage.getItem('opslog.distanceMiles') === '1');
const [region, setRegion] = useState<IaruRegion>(() => iaruRegion());
const [clusterWorkedSameSlot, setClusterWorkedSameSlot] = useState(() => localStorage.getItem('opslog.clusterWorkedSameSlot') === '1');
@@ -2812,7 +2824,6 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
}
}
const breadcrumb = useMemo(() => { const k = SECTION_KEY[selected]; return k ? t(k) : (SECTION_LABELS[selected] ?? selected); }, [selected, t]);
// === Section content renderers ===
@@ -8106,6 +8117,24 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
<Checkbox checked={groupDigital} onCheckedChange={(c) => { const v = !!c; setGroupDigital(v); writeUiPref('opslog.groupDigitalSlots', v ? '1' : '0'); }} />
<span title={t('gen.groupDigitalHint')}>{t('gen.groupDigital')}</span>
</label>
{/* Which digital row the band matrix opens on. An operator who works
only FT8 was shown DIG every time and had to click through to the
mode they actually use, on every callsign. The row still rotates
this only says where it starts. */}
<div className="flex items-center gap-2 text-sm">
<span title={t('gen.matrixDigiHint')}>{t('gen.matrixDigi')}</span>
<Select value={matrixDigi || '_'} onValueChange={(v) => {
const next = v === '_' ? '' : v;
setMatrixDigi(next);
writeUiPref(MATRIX_DIGI_KEY, next);
}}>
<SelectTrigger className="h-8 w-36"><SelectValue /></SelectTrigger>
<SelectContent>
<SelectItem value="_">DIGI</SelectItem>
{digitalModeNames.map((m) => <SelectItem key={m} value={m}>{m}</SelectItem>)}
</SelectContent>
</Select>
</div>
<label className="flex items-center gap-2 text-sm cursor-pointer">
{/* Distances are computed in km everywhere and converted at display
time see lib/units. Changing this repaints the columns that
@@ -8878,10 +8907,11 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
</aside>
{/* Right content pane */}
{/* No breadcrumb line. It said the same word as the heading right
underneath it "GENERAL" over "General" and the sidebar
beside it already shows which section is open, highlighted. Two
lines and a highlight for one fact. */}
<div className="overflow-y-auto p-6">
<div className="text-[10px] uppercase tracking-wider text-muted-foreground mb-3 font-semibold">
{breadcrumb}
</div>
<PanelHost key={selected} render={PANELS[selected]} />
{err && (