feat: Adding show password for SMTP server

This commit is contained in:
2026-07-17 20:50:05 +02:00
parent 6322a425d8
commit 031dfa8f46
4 changed files with 46 additions and 7 deletions
+11 -3
View File
@@ -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<QSO>(() => JSON.parse(JSON.stringify(qso)));
// Per-mode RST dropdown choices, loaded from the same settings as the entry form.
const [rstLists, setRstLists] = useState<RSTLists>({ 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)} />
</div>
<div className="flex flex-col w-20"><Label>S</Label>
<Input value={draft.rst_sent ?? ''} onChange={(e) => set('rst_sent', e.target.value)} className="font-mono" /></div>
<Combobox value={draft.rst_sent ?? ''} options={rstOptions(draft.mode ?? '', rstLists)} allowFreeText commitOnType onChange={(v) => set('rst_sent', v)} /></div>
<div className="flex flex-col w-20"><Label>R</Label>
<Input value={draft.rst_rcvd ?? ''} onChange={(e) => set('rst_rcvd', e.target.value)} className="font-mono" /></div>
<Combobox value={draft.rst_rcvd ?? ''} options={rstOptions(draft.mode ?? '', rstLists)} allowFreeText commitOnType onChange={(v) => set('rst_rcvd', v)} /></div>
<Button type="button" variant="outline" className="h-10" onClick={fetchLookup} disabled={looking}
title={t('qedit.fetchTitle')}>
{looking ? <Loader2 className="size-4 animate-spin" /> : <Search className="size-4" />} {t('qedit.fetch')}
+11 -2
View File
@@ -3,7 +3,7 @@ import {
ArrowDown, ArrowUp, ArrowLeft, ArrowRight, Copy, Plus, Star, StarOff, Trash2,
ChevronDown, ChevronRight,
User, Database, Radio, Cog, Server, Award, Antenna as AntennaIcon,
Compass, Wifi, Construction, UploadCloud, Loader2, FolderOpen, Play, Power, Check,
Compass, Wifi, Construction, UploadCloud, Loader2, FolderOpen, Play, Power, Check, Eye, EyeOff,
} from 'lucide-react';
import {
GetLookupSettings, SaveLookupSettings, ClearLookupCache, TestLookupProvider,
@@ -945,6 +945,7 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
from: '', reply_to: '', encryption: 'starttls', auth: true, auto_send: false, subject: '', body: '',
});
const [emailMsg, setEmailMsg] = useState('');
const [showSmtpPass, setShowSmtpPass] = useState(false);
const setEmailField = (patch: Partial<EmailCfg>) => setEmailCfg((s) => ({ ...s, ...patch }));
// eQSL card e-mail (subject/body templates + auto-send on log).
type EQSLCfg = { subject: string; body: string; auto_send: boolean };
@@ -4325,7 +4326,15 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
<Label className="text-sm">{t('em.username')}</Label>
<Input className="h-8" disabled={!emailCfg.auth} value={emailCfg.smtp_user} onChange={(e) => setEmailField({ smtp_user: e.target.value })} />
<Label className="text-sm">{t('es.password')}</Label>
<Input type="password" className="h-8" disabled={!emailCfg.auth} value={emailCfg.smtp_password} onChange={(e) => setEmailField({ smtp_password: e.target.value })} />
<div className="relative">
<Input type={showSmtpPass ? 'text' : 'password'} className="h-8 pr-9" disabled={!emailCfg.auth} value={emailCfg.smtp_password} onChange={(e) => setEmailField({ smtp_password: e.target.value })} />
<button type="button" tabIndex={-1} onClick={() => setShowSmtpPass((v) => !v)}
title={showSmtpPass ? t('es.hidePass') : t('es.showPass')}
className="absolute inset-y-0 right-0 flex items-center px-2.5 text-muted-foreground hover:text-foreground disabled:opacity-40"
disabled={!emailCfg.auth}>
{showSmtpPass ? <EyeOff className="size-4" /> : <Eye className="size-4" />}
</button>
</div>
<Label className="text-sm">{t('em.fromAddr')}</Label>
<Input className="h-8" placeholder="[email protected]" value={emailCfg.from} onChange={(e) => setEmailField({ from: e.target.value })} />
<Label className="text-sm">{t('em.replyTo')}</Label>