From d7ee87f22d2c1adf5924af912ffda298031be64e Mon Sep 17 00:00:00 2001 From: rouggy Date: Sun, 30 Aug 2026 22:14:40 +0200 Subject: [PATCH] feat(ftx): the digital corner gets its own menu, and the watchlist learns to line up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An FTx menu between View and Tools gathers FT Decodes, FT Map and the Grid squares map — three views of the same UDP feed that were buried in Tools. And the watchlist spot rows swap the elastic country column for fixed widths, so band, mode and frequency read as columns instead of starting wherever each country name happened to end. --- frontend/src/App.tsx | 10 +++++++--- frontend/src/components/WatchlistTab.tsx | 11 ++++++----- frontend/src/lib/i18n.tsx | 4 ++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index ea149af..1c66eea 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -5117,13 +5117,17 @@ export default function App() { { type: 'item', label: t('view.refresh'), action: 'view.refresh', shortcut: 'F5' }, { type: 'item', label: t('view.clearFilters'), action: 'view.clearfilters' }, ]}, + // The digital-mode corner gets its own menu: the decode list, its map, + // and the grid-square chase all live off the same UDP feed. + { name: 'ftx', label: t('menu.ftx'), items: [ + { type: 'item', label: t('dec.tab'), action: 'tools.decodes' }, + { type: 'item', label: t('ftmap.tab'), action: 'tools.ftmap' }, + { type: 'item', label: t('gsm.title'), action: 'tools.grids' }, + ]}, { name: 'tools', label: t('menu.tools'), items: [ { type: 'item', label: t('tools.qslManager'), action: 'tools.qslmanager' }, { type: 'item', label: t('stats.tab'), action: 'tools.stats' }, { type: 'item', label: t('station.title'), action: 'tools.station' }, - { type: 'item', label: t('dec.tab'), action: 'tools.decodes' }, - { type: 'item', label: t('ftmap.tab'), action: 'tools.ftmap' }, - { type: 'item', label: t('gsm.title'), action: 'tools.grids' }, { type: 'item', label: t('tools.qslDesigner'), action: 'tools.qsldesigner' }, { type: 'separator' }, { type: 'item', label: (wkEnabled ? '✓ ' : '') + t('tools.winkeyer'), action: 'tools.winkeyer' }, diff --git a/frontend/src/components/WatchlistTab.tsx b/frontend/src/components/WatchlistTab.tsx index ff351a9..8da5477 100644 --- a/frontend/src/components/WatchlistTab.tsx +++ b/frontend/src/components/WatchlistTab.tsx @@ -391,11 +391,12 @@ export function WatchlistTab({ spots, spotStatus, onSpotSelect, onSpotClick }: P className={cn('w-full flex items-center gap-2 px-2 py-1.5 rounded text-[11px] bg-muted/25 hover:bg-muted/70 transition-colors text-left', !done && 'border-l-[3px] border-warning')}> {done && } - {s.dx_call} - {(s as any).country ?? ''} - {s.band} - {mode && {mode}} - {(s.freq_hz / 1e6).toFixed(4)} + {/* Fixed columns: an elastic country made band/mode/freq start wherever the name ended — every row its own ruler. */} + {s.dx_call} + {(s as any).country ?? ''} + {s.band} + {mode || ' '} + {(s.freq_hz / 1e6).toFixed(4)} {badge && chip(badge.color, badge.label)}
{done diff --git a/frontend/src/lib/i18n.tsx b/frontend/src/lib/i18n.tsx index fbea394..9d3df22 100644 --- a/frontend/src/lib/i18n.tsx +++ b/frontend/src/lib/i18n.tsx @@ -25,7 +25,7 @@ const en: Dict = { 'upd.retry': 'Retry', 'upd.browser': 'Open page', 'upd.checking': 'Checking for updates…', 'upd.upToDate': "You're up to date", 'rate.title': 'QSO rate (QSOs/hour) — projected from the last 10 / 60 minutes', 'lotw.feedStale': "ARRL's user list itself was last built on {date}, so this figure may be older than the station", 'lotw.userTip': 'LoTW user — last upload {date} ({days} days ago)', - 'menu.file': 'File', 'menu.edit': 'Edit', 'menu.view': 'View', 'menu.tools': 'Tools', + 'menu.ftx': 'FTx', 'menu.file': 'File', 'menu.edit': 'Edit', 'menu.view': 'View', 'menu.tools': 'Tools', 'file.import': 'Import ADIF…', 'file.export': 'Export ADIF…', 'file.exporting': 'Exporting…', 'file.exportCabrillo': 'Export Cabrillo…', 'file.deleteAll': 'Delete all QSOs…', 'file.exit': 'Exit', 'edit.editSel': 'Edit selected QSO…', 'edit.prefs': 'Preferences…', @@ -549,7 +549,7 @@ const fr: Dict = { 'live.stationsTitle': 'Stations on air', 'live.stationsEmpty': 'Aucune station ne reporte pour le moment.', 'live.stationsHide': 'Masquer', 'rate.title': 'Rythme QSO (QSO/heure) — projeté sur les 10 / 60 dernières minutes', 'lotw.feedStale': "la liste ARRL elle-même date du {date}, ce chiffre peut donc être plus vieux que la station", 'lotw.userTip': 'Utilisateur LoTW — dernier upload {date} (il y a {days} j)', - 'menu.file': 'Fichier', 'menu.edit': 'Édition', 'menu.view': 'Affichage', 'menu.tools': 'Outils', + 'menu.ftx': 'FTx', 'menu.file': 'Fichier', 'menu.edit': 'Édition', 'menu.view': 'Affichage', 'menu.tools': 'Outils', 'file.import': 'Importer ADIF…', 'file.export': 'Exporter ADIF…', 'file.exporting': 'Export…', 'file.exportCabrillo': 'Exporter Cabrillo…', 'file.deleteAll': 'Supprimer tous les QSO…', 'file.exit': 'Quitter', 'edit.editSel': 'Éditer le QSO sélectionné…', 'edit.prefs': 'Préférences…',