import { Mic, Square, X, Radio, Repeat } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; import { useI18n } from '@/lib/i18n'; export type DVKMsg = { slot: number; label: string; has_audio: boolean; duration_sec: number }; export type DVKStat = { recording: boolean; playing: boolean; rec_slot: number }; type Props = { messages: DVKMsg[]; status: DVKStat; onPlay: (slot: number) => void; onStop: () => void; onClose: () => void; autoCq: boolean; autoCqSecs: number; onToggleAutoCq: (on: boolean) => void; onSetAutoCqSecs: (n: number) => void; phoneOk: boolean; // false when the rig is on a non-phone mode → DVK TX blocked }; // Operating panel for the Digital Voice Keyer — transmits the recorded F1–F6 // voice messages to the rig ("To Radio"). Mirrors the WinKeyer panel's slot in // the reserved area. Recording/labeling lives in Settings → Audio. export function DvkPanel({ messages, status, onPlay, onStop, onClose, autoCq, autoCqSecs, onToggleAutoCq, onSetAutoCqSecs, phoneOk }: Props) { const { t } = useI18n(); const recorded = messages.filter((m) => m.has_audio); const anyAudio = recorded.length > 0; return (
{t('dvkp.voiceKeyer')} {status.playing && TX}
{!anyAudio ? (
{t('dvkp.noMsgPre')} {t('dvkp.settingsPath')} {t('dvkp.noMsgPost')}
) : ( // Only the recorded slots are shown. Two columns filling top-to-bottom // (rows sized to the count) — use the width instead of scrolling, so the // panel keeps the same height as the other reserved-area widgets.
{recorded.map((m) => ( ))}
)}
{/* Auto-CQ footer — repeats a CQ-labelled slot on a timer. Greyed out on a non-phone mode (the DVK won't transmit there). */}
{t('dvkp.gap')} onSetAutoCqSecs(parseInt(e.target.value, 10))} className="w-12 h-6 rounded border border-input bg-background px-1 text-[11px] font-mono text-center" /> s
{!phoneOk && (
{t('dvkp.notPhone')}
)}
); }