fix: restore theme on restart + consistent spot pills + red DVK TX

theme: self-heal the persisted theme after mount. The synchronous boot
read only looks at localStorage, which is empty when the WebView cleared
its storage or when syncPortablePrefs ran before the backend wired its
settings store (GetUIPref returned "" with no error) — so a restart could
silently land on the default light theme. ThemeProvider now re-reads the
portable pref from the DB once the backend is up (retrying briefly to ride
out a slow startup) and applies it, without clobbering a manual pick.

ClusterGrid: the Call cell now uses a danger pill for NEW DXCC, consistent
with the NEW BAND / NEW MODE pills, instead of a full-cell red fill. cellChip
inherits the column's font size (no fixed 9px / height) so a pill around a
callsign stays the same size as the plain callsigns beside it.

DvkPanel: the voice-keyer TX indicator (LED + label) is red while
transmitting, not orange.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
2026-07-18 19:28:55 +02:00
co-authored by Claude Opus 4.8
parent 3ed9f29d9a
commit 5abe4bd0c3
3 changed files with 49 additions and 14 deletions
+2 -2
View File
@@ -25,8 +25,8 @@ export function DvkPanel({ messages, status, onPlay, onStop, onClose }: Props) {
<div className="flex items-center gap-2 px-3 py-1.5 border-b border-border bg-muted/40 shrink-0">
<Mic className="size-3.5 text-primary" />
<span className="text-[11px] font-semibold uppercase tracking-wider">{t('dvkp.voiceKeyer')}</span>
<span className={cn('size-2 rounded-full', status.playing ? 'bg-warning animate-pulse' : 'bg-success')} />
{status.playing && <span className="text-[10px] text-warning font-medium">tx...</span>}
<span className={cn('size-2 rounded-full', status.playing ? 'bg-danger animate-pulse' : 'bg-success')} />
{status.playing && <span className="text-[10px] text-danger font-medium">TX</span>}
<div className="flex-1" />
<Button variant="ghost" size="sm" className="h-6 px-2 text-[11px]" onClick={onStop} disabled={!status.playing}>
<Square className="size-3" /> {t('dvkp.stop')}