From 031dfa8f469205f82c3d9b308483f8be9d7652dd Mon Sep 17 00:00:00 2001 From: rouggy Date: Fri, 17 Jul 2026 20:50:05 +0200 Subject: [PATCH] feat: Adding show password for SMTP server --- frontend/src/components/QSOEditModal.tsx | 14 +++++++++++--- frontend/src/components/SettingsModal.tsx | 13 +++++++++++-- frontend/src/lib/i18n.tsx | 4 ++-- frontend/src/lib/rst.ts | 22 ++++++++++++++++++++++ 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/QSOEditModal.tsx b/frontend/src/components/QSOEditModal.tsx index f6726d6..e0867c5 100644 --- a/frontend/src/components/QSOEditModal.tsx +++ b/frontend/src/components/QSOEditModal.tsx @@ -1,6 +1,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'; import { Trash2, Search, Loader2 } from 'lucide-react'; -import { LookupCallsign, DXCCForCountry, GetAwardDefs, ComputeQSOAwardRefs } from '../../wailsjs/go/main/App'; +import { LookupCallsign, DXCCForCountry, GetAwardDefs, ComputeQSOAwardRefs, GetListsSettings } from '../../wailsjs/go/main/App'; +import { rstOptions, type RSTLists } from '@/lib/rst'; import { AwardRefSelector } from '@/components/AwardRefSelector'; import { AdifExtrasEditor } from '@/components/AdifExtrasEditor'; import { applyAwardRefs } from '@/lib/awardRefs'; @@ -175,6 +176,13 @@ export function QSOEditModal({ qso, onSave, onDelete, onClose, countries = [], b return base; }, [modes, qso.mode]); const [draft, setDraft] = useState(() => JSON.parse(JSON.stringify(qso))); + // Per-mode RST dropdown choices, loaded from the same settings as the entry form. + const [rstLists, setRstLists] = useState({ phone: [], cw: [], digital: [] }); + useEffect(() => { + GetListsSettings() + .then((l: any) => setRstLists({ phone: l?.rst_phone ?? [], cw: l?.rst_cw ?? [], digital: l?.rst_digital ?? [] })) + .catch(() => {}); + }, []); // Frequencies are edited as kHz + Hz (Log4OM style) and recombined on save. const splitHz = (hz?: number) => hz ? { khz: String(Math.floor(hz / 1000)), hz: String(hz % 1000).padStart(3, '0') } @@ -404,9 +412,9 @@ export function QSOEditModal({ qso, onSave, onDelete, onClose, countries = [], b value={draft.callsign ?? ''} onChange={(e) => set('callsign', e.target.value)} />
- set('rst_sent', e.target.value)} className="font-mono" />
+ set('rst_sent', v)} />
- set('rst_rcvd', e.target.value)} className="font-mono" />
+ set('rst_rcvd', v)} /> + setEmailField({ from: e.target.value })} /> diff --git a/frontend/src/lib/i18n.tsx b/frontend/src/lib/i18n.tsx index b19ca3a..90a838e 100644 --- a/frontend/src/lib/i18n.tsx +++ b/frontend/src/lib/i18n.tsx @@ -195,7 +195,7 @@ const en: Dict = { 'cat.rotatorOk': "Packet sent — antenna should swing to 0° (north). If it didn't, check PstRotator host/port and that PstRotator's UDP listener is enabled.", 'cat.ubOk': 'Connected — the antenna responded with a status frame.', // External services (repeated labels) - 'es.autoUpload': 'Automatic upload on new QSO', 'es.uploadTiming': 'Upload timing', 'es.immediate': 'Immediate', 'es.delayed': 'Delayed (1–2 min, lets you fix mistakes)', 'es.onClose': 'On app close (batch)', 'es.testConn': 'Test connection', 'es.testing': 'Testing…', 'es.password': 'Password', 'es.apiKey': 'API key', 'es.forceCall': 'Force station callsign', 'es.accountEmail': 'Account email', 'es.logbookCall': 'Logbook callsign', + 'es.autoUpload': 'Automatic upload on new QSO', 'es.uploadTiming': 'Upload timing', 'es.immediate': 'Immediate', 'es.delayed': 'Delayed (1–2 min, lets you fix mistakes)', 'es.onClose': 'On app close (batch)', 'es.testConn': 'Test connection', 'es.testing': 'Testing…', 'es.password': 'Password', 'es.showPass': 'Show password', 'es.hidePass': 'Hide password', 'es.apiKey': 'API key', 'es.forceCall': 'Force station callsign', 'es.accountEmail': 'Account email', 'es.logbookCall': 'Logbook callsign', 'lotw.usersTitle': 'LoTW user list', 'lotw.usersHint': "Downloads ARRL's public list of LoTW users + their last-upload date, to show a colour-coded LoTW badge next to a callsign (green < 1 week · amber 1–4 weeks · red > 30 days).", 'lotw.usersDownload': 'Download LoTW user list', 'lotw.usersDownloading': 'Downloading…', 'lotw.usersLoaded': '{n} users loaded · updated {date}', 'lotw.usersNone': 'Not downloaded yet — the badge stays hidden until you do.', 'hw.connecting': 'Connecting…', 'hw.testConn': 'Test connection', 'hw.sending': 'Sending…', 'hw.testRotator': 'Test (point to 0°)', // Profiles panel @@ -462,7 +462,7 @@ const fr: Dict = { 'cat.flexHint': "API SmartSDR native — pas besoin d'OmniRig. Fréquence, mode et split sont lus en temps réel depuis la radio (sans poll, sans le bug du mode au 2ᵉ clic). Utilise Détecter les radios ou saisis l'IP. Le mode numérique par défaut est ce qu'OpsLog logge quand la slice est en mode numérique (DIGU/DIGL).", 'cat.rotatorOk': "Paquet envoyé — l'antenne devrait tourner vers 0° (nord). Sinon, vérifie l'hôte/port PstRotator et que l'écouteur UDP de PstRotator est activé.", 'cat.ubOk': "Connecté — l'antenne a répondu avec une trame de statut.", - 'es.autoUpload': 'Envoi automatique à chaque nouveau QSO', 'es.uploadTiming': "Moment de l'envoi", 'es.immediate': 'Immédiat', 'es.delayed': 'Différé (1–2 min, permet de corriger les erreurs)', 'es.onClose': "À la fermeture (par lot)", 'es.testConn': 'Tester la connexion', 'es.testing': 'Test…', 'es.password': 'Mot de passe', 'es.apiKey': 'Clé API', 'es.forceCall': "Forcer l'indicatif de station", 'es.accountEmail': 'E-mail du compte', 'es.logbookCall': 'Indicatif du carnet', + 'es.autoUpload': 'Envoi automatique à chaque nouveau QSO', 'es.uploadTiming': "Moment de l'envoi", 'es.immediate': 'Immédiat', 'es.delayed': 'Différé (1–2 min, permet de corriger les erreurs)', 'es.onClose': "À la fermeture (par lot)", 'es.testConn': 'Tester la connexion', 'es.testing': 'Test…', 'es.password': 'Mot de passe', 'es.showPass': 'Afficher le mot de passe', 'es.hidePass': 'Masquer le mot de passe', 'es.apiKey': 'Clé API', 'es.forceCall': "Forcer l'indicatif de station", 'es.accountEmail': 'E-mail du compte', 'es.logbookCall': 'Indicatif du carnet', 'lotw.usersTitle': 'Liste des utilisateurs LoTW', 'lotw.usersHint': "Télécharge la liste publique ARRL des utilisateurs LoTW + leur date de dernier upload, pour afficher un badge LoTW coloré à côté d'un indicatif (vert < 1 semaine · ambre 1–4 semaines · rouge > 30 j).", 'lotw.usersDownload': 'Télécharger la liste LoTW', 'lotw.usersDownloading': 'Téléchargement…', 'lotw.usersLoaded': '{n} utilisateurs chargés · maj {date}', 'lotw.usersNone': 'Pas encore téléchargée — le badge reste caché tant que ce n’est pas fait.', 'hw.connecting': 'Connexion…', 'hw.testConn': 'Tester la connexion', 'hw.sending': 'Envoi…', 'hw.testRotator': 'Tester (pointer vers 0°)', 'prof.deleteConfirm': 'Supprimer le profil « {name} » ? Tous ses réglages seront perdus.', 'prof.dupPrompt': 'Nom du nouveau profil (copie de « {name} ») :', 'prof.dupSuffix': '{name} Copie', 'prof.newPrompt': 'Nom du nouveau profil :', 'prof.newDefault': 'Nouveau profil', diff --git a/frontend/src/lib/rst.ts b/frontend/src/lib/rst.ts index 3d0837d..64e5d09 100644 --- a/frontend/src/lib/rst.ts +++ b/frontend/src/lib/rst.ts @@ -14,3 +14,25 @@ export function sMeterRST(s: number, overDb: number, mode?: string): string { if (overDb > 0) return `59+${Math.ceil(overDb / 5) * 5}`; return `5${strength}`; } + +// RST dropdown lists, shared by the entry form and the QSO editor so both offer +// the same per-mode choices (Settings → Modes → RST report lists). +export type RSTLists = { phone: string[]; cw: string[]; digital: string[] }; + +// rstCategory maps an ADIF mode to its RST family (phone / cw / digital). +export function rstCategory(mode: string): keyof RSTLists { + const m = (mode || '').toUpperCase(); + const digital = ['FT8', 'FT4', 'JT65', 'JT9', 'JS8', 'Q65', 'MSK144', 'FST4', 'FST4W', 'MFSK', 'OLIVIA', 'JT4', 'WSPR']; + if (digital.includes(m)) return 'digital'; + if (['CW', 'RTTY', 'PSK31', 'PSK63', 'PSK', 'PSK125'].includes(m)) return 'cw'; + return 'phone'; +} + +// rstOptions returns the valid report choices for a mode from the user's +// editable lists, with a tiny fallback before they load. +export function rstOptions(mode: string, lists: RSTLists): string[] { + const cat = rstCategory(mode); + const l = lists[cat]; + if (l && l.length) return l; + return cat === 'phone' ? ['59', '58', '57'] : cat === 'cw' ? ['599', '589', '579'] : ['+00', '-10', '-20']; +}