feat: upload qrz.com clublog and lotw manually

This commit is contained in:
2026-05-29 00:16:59 +02:00
parent edda183c16
commit 33a7b6c4ac
12 changed files with 1113 additions and 41 deletions
+18
View File
@@ -27,6 +27,7 @@ import type { adif as adifModels, lookup as lookupModels, cat as catModels } fro
import type { QSOForm, WorkedBeforeView, StationSettingsForm, ListsSettingsForm, ModePresetForm } from '@/types';
import { Menubar, type Menu } from '@/components/Menubar';
import { QSLManagerModal } from '@/components/QSLManagerModal';
import { ConfirmDialog } from '@/components/ConfirmDialog';
import { SettingsModal } from '@/components/SettingsModal';
import { QSOEditModal } from '@/components/QSOEditModal';
@@ -448,6 +449,7 @@ export default function App() {
// close so the next plain "Preferences" launch reverts to default.
const [settingsSection, setSettingsSection] = useState<string | undefined>(undefined);
const [showDeleteAll, setShowDeleteAll] = useState(false);
const [showQSLManager, setShowQSLManager] = useState(false);
const [deletingAll, setDeletingAll] = useState(false);
const [ctyRefreshing, setCtyRefreshing] = useState(false);
@@ -505,6 +507,17 @@ export default function App() {
}
}, [filterCallsign, filterBand, filterMode, qsoLimit]);
// Refresh the Recent QSOs grid after external-service uploads stamp the
// sent status (auto-upload via extsvc:uploaded, or manual QSL Manager via
// qslmgr:done). Debounced so a batch of per-QSO events triggers one reload.
useEffect(() => {
let t: number | undefined;
const ping = () => { if (t) window.clearTimeout(t); t = window.setTimeout(() => { refresh(); }, 400); };
const offUploaded = EventsOn('extsvc:uploaded', ping);
const offDone = EventsOn('qslmgr:done', ping);
return () => { offUploaded(); offDone(); if (t) window.clearTimeout(t); };
}, [refresh]);
const loadStation = useCallback(async () => {
try { setStation(await GetStationSettings()); } catch {}
}, []);
@@ -965,6 +978,8 @@ export default function App() {
{ type: 'item', label: 'Clear filters', action: 'view.clearfilters' },
]},
{ name: 'tools', label: 'Tools', items: [
{ type: 'item', label: 'QSL Manager…', action: 'tools.qslmanager' },
{ type: 'separator' },
{ type: 'item', label: 'Callsign lookup settings…', action: 'tools.lookup' },
{ type: 'item', label: 'DX Cluster', action: 'tools.cluster', disabled: true },
{ type: 'item', label: 'CAT control', action: 'tools.cat', disabled: true },
@@ -989,6 +1004,7 @@ export default function App() {
case 'edit.edit': if (selectedId !== null) openEdit(selectedId); break;
case 'edit.delete': if (selectedId !== null) askDelete(selectedId); break;
case 'edit.prefs': setShowSettings(true); break;
case 'tools.qslmanager': setShowQSLManager(true); break;
case 'tools.lookup': setSettingsSection('lookup'); setShowSettings(true); break;
case 'tools.refreshCty': refreshCtyDat(); break;
}
@@ -1979,6 +1995,8 @@ export default function App() {
onSaved={() => { loadStation(); loadLists(); loadCATCfg(); }}
/>
)}
<QSLManagerModal open={showQSLManager} onClose={() => setShowQSLManager(false)} />
{deletingQSO && (
<ConfirmDialog
title="Delete QSO?"