feat(bandmap): fold the legend away
A legend is a reference, not a running display: once its colours are learnt it spends four lines of a short screen saying nothing new. A chevron in the footer folds it, the same chevron brings it back, and the choice survives a restart.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { Minus, Plus, Crosshair, X, PanelLeft, PanelRight } from 'lucide-react';
|
||||
import { Minus, Plus, Crosshair, X, PanelLeft, PanelRight, ChevronDown, ChevronUp } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
import { bandRange, bandSegments, subscribeIaruRegion, type SegMode } from '@/lib/bandplan';
|
||||
@@ -283,6 +283,17 @@ export function BandMap({ band, spots, spotStatus: spotStatusRaw, currentFreqHz,
|
||||
const range = bandRange(band);
|
||||
const segments = bandSegments(band).map(([a, b, m]) => [a, b, SEG_COLOR[m]] as [number, number, string]);
|
||||
const [zoomIdx, setZoomIdx] = useState(() => readZoom(band));
|
||||
// The legend is a reference, not a running display: once its colours are
|
||||
// learnt it is four lines of a short screen spent saying nothing new. Folded
|
||||
// away by a toggle, and the choice is remembered.
|
||||
const [legendOpen, setLegendOpen] = useState(() => {
|
||||
try { return localStorage.getItem('opslog.bmpLegend') !== '0'; } catch { return true; }
|
||||
});
|
||||
const toggleLegend = () => setLegendOpen((v) => {
|
||||
const next = !v;
|
||||
try { localStorage.setItem('opslog.bmpLegend', next ? '1' : '0'); } catch { /* private mode */ }
|
||||
return next;
|
||||
});
|
||||
// The docked map follows the rig, so a band change must bring up THAT band's
|
||||
// remembered zoom.
|
||||
useEffect(() => { setZoomIdx(readZoom(band)); }, [band]);
|
||||
@@ -753,6 +764,7 @@ export function BandMap({ band, spots, spotStatus: spotStatusRaw, currentFreqHz,
|
||||
</div>
|
||||
</div>
|
||||
{/* Colour legend — what each pill colour means. */}
|
||||
{legendOpen && (
|
||||
<div className="px-3 py-1 flex flex-wrap items-center gap-x-2.5 gap-y-0.5 text-[9px] text-muted-foreground bg-muted/20 border-t border-border">
|
||||
<LegendDot cls="bg-danger" label={t('bmp.legendNewDxcc')} />
|
||||
<LegendDot cls="bg-warning" label={t('bmp.legendNewBand')} />
|
||||
@@ -769,9 +781,18 @@ export function BandMap({ band, spots, spotStatus: spotStatusRaw, currentFreqHz,
|
||||
<LegendDot colour={SEG_COLOR.digi} label={t("bmp.legendData")} />
|
||||
<LegendDot colour={SEG_COLOR.phone} label={t("bmp.legendPhone")} />
|
||||
</div>
|
||||
<div className="px-3 py-1 text-[9px] text-muted-foreground bg-muted/30 border-t border-border font-mono text-center shrink-0">
|
||||
{t('bmp.footerHint')}
|
||||
{hidden > 0 && <span className="text-warning"> · {t('bmp.spotsHidden', { n: hidden, max: MAX_VISIBLE_SPOTS })}</span>}
|
||||
)}
|
||||
<div className="px-3 py-1 flex items-center gap-2 text-[9px] text-muted-foreground bg-muted/30 border-t border-border font-mono shrink-0">
|
||||
<span className="flex-1 text-center">
|
||||
{t('bmp.footerHint')}
|
||||
{hidden > 0 && <span className="text-warning"> · {t('bmp.spotsHidden', { n: hidden, max: MAX_VISIBLE_SPOTS })}</span>}
|
||||
</span>
|
||||
<button type="button" onClick={toggleLegend}
|
||||
title={legendOpen ? t('bmp.legendHide') : t('bmp.legendShow')}
|
||||
aria-label={legendOpen ? t('bmp.legendHide') : t('bmp.legendShow')}
|
||||
className="shrink-0 inline-flex items-center gap-0.5 rounded px-1 py-px hover:bg-muted hover:text-foreground">
|
||||
{legendOpen ? <ChevronDown className="size-3" /> : <ChevronUp className="size-3" />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user