fix(cat): the chip says what YOU called the radio

It showed what the radio calls itself over CAT — 'Kenwood (911)' for a K3,
a bare 'CAT' for a Flex that reports nothing useful. That is the answer to
a question nobody asks once the rig has a name in the list, and it made
the two radios look alike in the one place they have to be told apart.

The name the operator typed comes first now, on the chip and in the menu,
and falls back to the radio's own identity when they typed none. The model
identity is still in the tooltip, where it answers 'what is actually
connected' without taking the place of 'which of my rigs is this'.
This commit is contained in:
2026-08-27 00:42:26 +02:00
parent cf5efea3e4
commit 2594697e00
4 changed files with 25 additions and 8 deletions
+14 -6
View File
@@ -313,9 +313,17 @@ function RadioChip({ catUp, catState, onOpenSettings }: {
return () => document.removeEventListener('mousedown', onDoc);
}, [open]);
// What the operator called this radio comes first.
//
// The chip showed what the RADIO calls itself over CAT — "Kenwood (911)" for
// a K3, a bare "CAT" for a Flex that reports nothing useful — which is the
// answer to a question nobody asked once the rig has a name in the list. The
// model identity is still there, in the tooltip.
const active = radios.find((r: any) => r.active);
const named = (active?.name || '').trim();
const label = catUp
? (catState.rig || 'CAT')
: (catState.enabled ? (shortCatError(catState.error) || 'CAT off') : 'CAT');
? (named || catState.rig || 'CAT')
: (catState.enabled ? (named || shortCatError(catState.error) || 'CAT off') : (named || 'CAT'));
// The menu opens with ONE radio too.
//
// It was only shown from two, on the reasoning that a single radio has
@@ -330,9 +338,9 @@ function RadioChip({ catUp, catState, onOpenSettings }: {
<button
type="button"
onClick={() => { if (!has) { onOpenSettings(); return; } load(); setOpen((o) => !o); }}
title={has
? 'Radios — right-click for the CAT settings'
: (catUp ? `CAT: ${catState.rig || catState.backend || 'connected'}` : (catState.error || 'CAT'))}
title={catUp
? `${catState.rig || catState.backend || 'connected'}${has ? ' — click to switch radio, right-click for the CAT settings' : ''}`
: (catState.error || 'CAT')}
onContextMenu={(e) => { e.preventDefault(); onOpenSettings(); }}
className={cn('inline-flex items-center gap-1.5 h-5 px-2 rounded-full border text-[11px] transition-colors',
'border-border hover:bg-muted cursor-pointer')}
@@ -356,7 +364,7 @@ function RadioChip({ catUp, catState, onOpenSettings }: {
r.active && 'font-semibold text-primary')}
>
<span className={cn('size-1.5 rounded-full shrink-0', r.active ? 'bg-success' : 'bg-muted-foreground/30')} />
<span className="flex-1 truncate">{r.name}</span>
<span className="flex-1 truncate">{(r.name || '').trim() || r.label}</span>
<span className="text-[10px] text-muted-foreground uppercase">{r.backend}</span>
</button>
))}
+1 -1
View File
@@ -3224,7 +3224,7 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
<SelectTrigger className="h-9 flex-1"><SelectValue placeholder={t('cat.radio')} /></SelectTrigger>
<SelectContent>
{radios.map((r: any, i: number) => (
<SelectItem key={r.id} value={r.id}>{r.name?.trim() || `Radio ${i + 1}`}</SelectItem>
<SelectItem key={r.id} value={r.id}>{r.name?.trim() || r.label || `Radio ${i + 1}`}</SelectItem>
))}
</SelectContent>
</Select>
+2
View File
@@ -3606,6 +3606,7 @@ export namespace main {
export class RadioListEntry {
id: string;
name: string;
label: string;
backend: string;
active: boolean;
@@ -3617,6 +3618,7 @@ export namespace main {
if ('string' === typeof source) source = JSON.parse(source);
this.id = source["id"];
this.name = source["name"];
this.label = source["label"];
this.backend = source["backend"];
this.active = source["active"];
}