feat: Flexradio/Icom, click on signal to fill the RST tx
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
} from '../../wailsjs/go/main/App';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
import { sMeterRST } from '@/lib/rst';
|
||||
|
||||
type FlexState = {
|
||||
available: boolean; model?: string;
|
||||
@@ -140,15 +141,17 @@ function LevelRow({ label, on, onToggle, value, onLevel, disabled, accent, slide
|
||||
// `display` overrides the numeric readout; `segColor` colours segments by their
|
||||
// 0..1 position (zones); the top ~18% light red by default (overload/peak).
|
||||
const METER_SEGMENTS = 26;
|
||||
function MeterBar({ label, value, unit, lo, hi, accent = '#16a34a', extra, display, segColor }: {
|
||||
function MeterBar({ label, value, unit, lo, hi, accent = '#16a34a', extra, display, segColor, onClick, title }: {
|
||||
label: string; value: number; unit?: string; lo: number; hi: number; accent?: string; extra?: string; display?: string;
|
||||
segColor?: (frac: number) => string;
|
||||
segColor?: (frac: number) => string; onClick?: () => void; title?: string;
|
||||
}) {
|
||||
const span = hi - lo;
|
||||
const pct = span > 0 ? Math.max(0, Math.min(100, ((value - lo) / span) * 100)) : 0;
|
||||
const lit = Math.round((pct / 100) * METER_SEGMENTS);
|
||||
return (
|
||||
<div className="rounded-lg border border-border/70 px-2.5 py-2 bg-gradient-to-b from-card to-muted/40 shadow-sm min-w-0">
|
||||
<div onClick={onClick} title={title}
|
||||
className={cn('rounded-lg border border-border/70 px-2.5 py-2 bg-gradient-to-b from-card to-muted/40 shadow-sm min-w-0',
|
||||
onClick && 'cursor-pointer hover:border-primary/60 hover:from-muted/40')}>
|
||||
<div className="flex items-baseline justify-between gap-1 mb-1.5">
|
||||
<span className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground truncate">{label}</span>
|
||||
<span className="text-sm font-mono font-bold tabular-nums whitespace-nowrap text-foreground/90">
|
||||
@@ -190,7 +193,7 @@ function Card({ icon: Icon, title, accent, children }: { icon: any; title: strin
|
||||
|
||||
// onCWSpeed (optional): notified when the operator changes CW speed here, so the
|
||||
// host can keep the WinKeyer (which actually sends the macros) in sync.
|
||||
export function FlexPanel({ onCWSpeed }: { onCWSpeed?: (wpm: number) => void } = {}) {
|
||||
export function FlexPanel({ onCWSpeed, onReportRST }: { onCWSpeed?: (wpm: number) => void; onReportRST?: (rst: string) => void } = {}) {
|
||||
const { t } = useI18n();
|
||||
const [st, setSt] = useState<FlexState>(ZERO);
|
||||
const hold = useRef<Record<string, number>>({});
|
||||
@@ -547,17 +550,19 @@ export function FlexPanel({ onCWSpeed }: { onCWSpeed?: (wpm: number) => void } =
|
||||
: /volt/i.test(m.unit || '') ? '#2563eb' : '#16a34a';
|
||||
// S-meter: dBm → S-units (S9 = -73 dBm on HF, 6 dB per unit).
|
||||
const sUnit = (dbm: number) => {
|
||||
const s = (dbm + 127) / 6; // S0 = -127 dBm
|
||||
if (s >= 9) {
|
||||
const over = Math.round(dbm + 73); // dB over S9
|
||||
return { display: over > 0 ? `S9+${over}` : 'S9', bar: s };
|
||||
const sv = (dbm + 127) / 6; // S0 = -127 dBm
|
||||
if (sv >= 9) {
|
||||
const over = Math.max(0, Math.round(dbm + 73)); // dB over S9
|
||||
return { display: over > 0 ? `S9+${over}` : 'S9', bar: sv, s: 9, over };
|
||||
}
|
||||
return { display: `S${Math.max(0, Math.round(s))}`, bar: Math.max(0, s) };
|
||||
return { display: `S${Math.max(0, Math.round(sv))}`, bar: Math.max(0, sv), s: Math.max(0, sv), over: 0 };
|
||||
};
|
||||
const cur = [
|
||||
sig && (() => { const dbm = peakHold('s', sig.value); const s = sUnit(dbm); return (
|
||||
<MeterBar key="s" label="S-METER" value={s.bar} lo={0} hi={19} accent="#16a34a" display={s.display} extra={`${dbm.toFixed(1)} dBm`}
|
||||
segColor={(fr) => { const sv = fr * 19; return sv < 9 ? '#16a34a' : sv < 12.33 ? '#f59e0b' : '#dc2626'; }} />
|
||||
title={onReportRST ? t('rst.clickToFill') : undefined}
|
||||
onClick={onReportRST ? () => onReportRST(sMeterRST(s.s, s.over, st.mode)) : undefined}
|
||||
segColor={(fr) => { const sval = fr * 19; return sval < 9 ? '#16a34a' : sval < 12.33 ? '#f59e0b' : '#dc2626'; }} />
|
||||
); })(),
|
||||
fwd && (() => { const w = peakHold('p', isDbm(fwd) ? dbmToW(fwd.value) : fwd.value); return (
|
||||
<MeterBar key="p" label="PWR" unit="W" lo={0} hi={120} accent="#dc2626"
|
||||
|
||||
Reference in New Issue
Block a user