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:
+8
-1
@@ -118,9 +118,16 @@ func (a *App) ActiveRadioID() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RadioListEntry is what the status-bar menu needs: enough to draw a row.
|
// RadioListEntry is what the status-bar menu needs: enough to draw a row.
|
||||||
|
//
|
||||||
|
// Name is what the OPERATOR typed, empty when they typed nothing; Label is what
|
||||||
|
// to draw when there is no better idea. The two are separate because the caller
|
||||||
|
// has a better idea than we do: the status bar knows what the radio calls
|
||||||
|
// itself over CAT, and "FTDX10" beats "Radio 2" — but only where the operator
|
||||||
|
// has not given it a name of their own, which beats both.
|
||||||
type RadioListEntry struct {
|
type RadioListEntry struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
Label string `json:"label"`
|
||||||
Backend string `json:"backend"`
|
Backend string `json:"backend"`
|
||||||
Active bool `json:"active"`
|
Active bool `json:"active"`
|
||||||
}
|
}
|
||||||
@@ -135,7 +142,7 @@ func (a *App) ListRadios() []RadioListEntry {
|
|||||||
out := make([]RadioListEntry, 0, len(list))
|
out := make([]RadioListEntry, 0, len(list))
|
||||||
for i, r := range list {
|
for i, r := range list {
|
||||||
out = append(out, RadioListEntry{
|
out = append(out, RadioListEntry{
|
||||||
ID: r.ID, Name: radioLabel(r, i),
|
ID: r.ID, Name: strings.TrimSpace(r.Name), Label: radioLabel(r, i),
|
||||||
Backend: r.Settings.Backend, Active: r.ID == active,
|
Backend: r.Settings.Backend, Active: r.ID == active,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-6
@@ -313,9 +313,17 @@ function RadioChip({ catUp, catState, onOpenSettings }: {
|
|||||||
return () => document.removeEventListener('mousedown', onDoc);
|
return () => document.removeEventListener('mousedown', onDoc);
|
||||||
}, [open]);
|
}, [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
|
const label = catUp
|
||||||
? (catState.rig || 'CAT')
|
? (named || catState.rig || 'CAT')
|
||||||
: (catState.enabled ? (shortCatError(catState.error) || 'CAT off') : 'CAT');
|
: (catState.enabled ? (named || shortCatError(catState.error) || 'CAT off') : (named || 'CAT'));
|
||||||
// The menu opens with ONE radio too.
|
// The menu opens with ONE radio too.
|
||||||
//
|
//
|
||||||
// It was only shown from two, on the reasoning that a single radio has
|
// It was only shown from two, on the reasoning that a single radio has
|
||||||
@@ -330,9 +338,9 @@ function RadioChip({ catUp, catState, onOpenSettings }: {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => { if (!has) { onOpenSettings(); return; } load(); setOpen((o) => !o); }}
|
onClick={() => { if (!has) { onOpenSettings(); return; } load(); setOpen((o) => !o); }}
|
||||||
title={has
|
title={catUp
|
||||||
? 'Radios — right-click for the CAT settings'
|
? `${catState.rig || catState.backend || 'connected'}${has ? ' — click to switch radio, right-click for the CAT settings' : ''}`
|
||||||
: (catUp ? `CAT: ${catState.rig || catState.backend || 'connected'}` : (catState.error || 'CAT'))}
|
: (catState.error || 'CAT')}
|
||||||
onContextMenu={(e) => { e.preventDefault(); onOpenSettings(); }}
|
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',
|
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')}
|
'border-border hover:bg-muted cursor-pointer')}
|
||||||
@@ -356,7 +364,7 @@ function RadioChip({ catUp, catState, onOpenSettings }: {
|
|||||||
r.active && 'font-semibold text-primary')}
|
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={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>
|
<span className="text-[10px] text-muted-foreground uppercase">{r.backend}</span>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -3224,7 +3224,7 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
|
|||||||
<SelectTrigger className="h-9 flex-1"><SelectValue placeholder={t('cat.radio')} /></SelectTrigger>
|
<SelectTrigger className="h-9 flex-1"><SelectValue placeholder={t('cat.radio')} /></SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{radios.map((r: any, i: number) => (
|
{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>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
|||||||
@@ -3606,6 +3606,7 @@ export namespace main {
|
|||||||
export class RadioListEntry {
|
export class RadioListEntry {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
label: string;
|
||||||
backend: string;
|
backend: string;
|
||||||
active: boolean;
|
active: boolean;
|
||||||
|
|
||||||
@@ -3617,6 +3618,7 @@ export namespace main {
|
|||||||
if ('string' === typeof source) source = JSON.parse(source);
|
if ('string' === typeof source) source = JSON.parse(source);
|
||||||
this.id = source["id"];
|
this.id = source["id"];
|
||||||
this.name = source["name"];
|
this.name = source["name"];
|
||||||
|
this.label = source["label"];
|
||||||
this.backend = source["backend"];
|
this.backend = source["backend"];
|
||||||
this.active = source["active"];
|
this.active = source["active"];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user