diff --git a/changelog.json b/changelog.json index c499fb6..e34db9e 100644 --- a/changelog.json +++ b/changelog.json @@ -3,10 +3,10 @@ "version": "0.27.4", "date": "", "en": [ - "FT decodes: the status column shows the two-letter US state when known — for the WAS chasers." + "FT decodes: a State column between the locator and the country — the two-letter badge plus the full name — for the WAS chasers." ], "fr": [ - "FT decodes : la colonne statut affiche l’état US en deux lettres quand il est connu — pour les chasseurs de WAS." + "FT decodes : une colonne État entre le locator et le pays — le badge deux lettres plus le nom complet — pour les chasseurs de WAS." ] }, { diff --git a/frontend/src/components/DecodesPanel.tsx b/frontend/src/components/DecodesPanel.tsx index 4cac8ee..166a500 100644 --- a/frontend/src/components/DecodesPanel.tsx +++ b/frontend/src/components/DecodesPanel.tsx @@ -228,7 +228,7 @@ const CELL_LAST = 'flex items-center min-w-0 px-2 gap-1 overflow-hidden'; // One declaration per column, in display order: the header, the widths and the // resize handles all read from this, so a column cannot be resized in the header // and stay the old width in the body. -type ColKey = 'time' | 'snr' | 'dt' | 'freq' | 'band' | 'mode' | 'msg' | 'grid' | 'country' | 'status'; +type ColKey = 'time' | 'snr' | 'dt' | 'freq' | 'band' | 'mode' | 'msg' | 'grid' | 'state' | 'country' | 'status'; const COLS: { key: ColKey; tkey: string; def: number; min: number }[] = [ { key: 'time', tkey: 'dec.colTime', def: 64, min: 44 }, { key: 'snr', tkey: 'dec.colSnr', def: 50, min: 36 }, @@ -242,9 +242,26 @@ const COLS: { key: ColKey; tkey: string; def: number; min: number }[] = [ // The grid was carried and shown nowhere: it drives the NEW GRID badge, and // an operator chasing squares could see the verdict but never the square. { key: 'grid', tkey: 'dec.colGrid', def: 62, min: 46 }, + // For the WAS chasers: the badge carries the two letters, the name spells + // them out — "SD" alone is a quiz for a European. + { key: 'state', tkey: 'dec.colState', def: 120, min: 56 }, { key: 'country', tkey: 'dec.colCountry', def: 140, min: 70 }, { key: 'status', tkey: 'dec.colStatus', def: 186, min: 80 }, ]; +const US_STATES: Record = { + AL: 'Alabama', AK: 'Alaska', AZ: 'Arizona', AR: 'Arkansas', CA: 'California', + CO: 'Colorado', CT: 'Connecticut', DE: 'Delaware', FL: 'Florida', GA: 'Georgia', + HI: 'Hawaii', ID: 'Idaho', IL: 'Illinois', IN: 'Indiana', IA: 'Iowa', + KS: 'Kansas', KY: 'Kentucky', LA: 'Louisiana', ME: 'Maine', MD: 'Maryland', + MA: 'Massachusetts', MI: 'Michigan', MN: 'Minnesota', MS: 'Mississippi', + MO: 'Missouri', MT: 'Montana', NE: 'Nebraska', NV: 'Nevada', NH: 'New Hampshire', + NJ: 'New Jersey', NM: 'New Mexico', NY: 'New York', NC: 'North Carolina', + ND: 'North Dakota', OH: 'Ohio', OK: 'Oklahoma', OR: 'Oregon', PA: 'Pennsylvania', + RI: 'Rhode Island', SC: 'South Carolina', SD: 'South Dakota', TN: 'Tennessee', + TX: 'Texas', UT: 'Utah', VT: 'Vermont', VA: 'Virginia', WA: 'Washington', + WV: 'West Virginia', WI: 'Wisconsin', WY: 'Wyoming', DC: 'District of Columbia', +}; + const COL_MAX = 600; const COLW_KEY = 'opslog.decodeColWidths'; @@ -1098,6 +1115,15 @@ export function DecodesPanel({ decodes, txMsgs, txState, txStates, spotStatus, o {d.grid || e?.grid || ''} + + {e?.state && ( + <> + {e.state} + {US_STATES[e.state.toUpperCase()] ?? ''} + + )} + + {e?.country ?? ''} @@ -1106,12 +1132,6 @@ export function DecodesPanel({ decodes, txMsgs, txState, txStates, spotStatus, o right edge, shortest first so the eye can scan the column rather than read it. */} - {/* The two-letter US state, when the log or the licence - data knows it — a WAS chaser reads the column for - exactly this. */} - {e?.state && ( - {e.state} - )} {e?.lotw && ( L )} diff --git a/frontend/src/lib/i18n.tsx b/frontend/src/lib/i18n.tsx index 5ee31de..ad061bb 100644 --- a/frontend/src/lib/i18n.tsx +++ b/frontend/src/lib/i18n.tsx @@ -176,7 +176,7 @@ const en: Dict = { 'dec.colFreq': 'Freq', 'dec.colFreqTitle': 'Audio offset inside the passband (Hz)', 'dec.txNow': 'Transmitting', 'dec.txIdle': 'Transmit', 'dec.working': 'calling', 'dec.toYou': 'to you', 'dec.txUnknown': 'transmitting — text not reported', 'dec.txNothing': 'nothing being sent', - 'dec.colTime': 'Time', 'dec.colSnr': 'SNR', 'dec.colMsg': 'Message', 'dec.bgGridUnconf': 'GRID?', 'dec.bgGridUnconfTip': 'This square is worked but not yet confirmed — a QSL to chase, not a QSO to make.', 'dec.colGrid': 'Grid', 'dec.colCountry': 'Country', 'dec.colBand': 'Band', 'dec.colMode': 'Mode', 'dec.colStatus': 'Status', 'dec.stateTip': 'US state', 'dec.wkd': 'Wkd', + 'dec.colTime': 'Time', 'dec.colSnr': 'SNR', 'dec.colMsg': 'Message', 'dec.bgGridUnconf': 'GRID?', 'dec.bgGridUnconfTip': 'This square is worked but not yet confirmed — a QSL to chase, not a QSO to make.', 'dec.colGrid': 'Grid', 'dec.colState': 'State', 'dec.colCountry': 'Country', 'dec.colBand': 'Band', 'dec.colMode': 'Mode', 'dec.colStatus': 'Status', 'dec.stateTip': 'US state', 'dec.wkd': 'Wkd', 'dec.bgPota': 'POTA', 'dec.bgGrid': 'GRID', 'dec.bgPfx': 'PFX', 'dec.bgCounty': 'CTY', 'dec.stNew': 'NEW', 'dec.stBand': 'BAND', 'dec.stMode': 'MODE', 'dec.stSlot': 'SLOT', 'dec.stCall': 'CALL', 'dec.empty': 'Nothing decoded yet. Decodes arrive from WSJT-X, JTDX or MSHV over the inbound UDP link (Settings -> UDP).', @@ -696,7 +696,7 @@ const fr: Dict = { 'dec.colFreq': 'Freq', 'dec.colFreqTitle': 'Decalage audio dans la bande passante (Hz)', 'dec.txNow': 'En emission', 'dec.txIdle': 'Emission', 'dec.working': 'appelle', 'dec.toYou': 'pour toi', 'dec.txUnknown': 'en émission — texte non communiqué', 'dec.txNothing': 'rien en cours d’émission', - 'dec.colTime': 'Heure', 'dec.colSnr': 'SNR', 'dec.colMsg': 'Message', 'dec.bgGridUnconf': 'GRID?', 'dec.bgGridUnconfTip': 'Ce carré est contacté mais pas encore confirmé — une QSL à relancer, pas un QSO à faire.', 'dec.colGrid': 'Locator', 'dec.colCountry': 'Pays', 'dec.colBand': 'Bande', 'dec.colMode': 'Mode', 'dec.colStatus': 'Statut', 'dec.stateTip': 'État US', 'dec.wkd': 'Fait', + 'dec.colTime': 'Heure', 'dec.colSnr': 'SNR', 'dec.colMsg': 'Message', 'dec.bgGridUnconf': 'GRID?', 'dec.bgGridUnconfTip': 'Ce carré est contacté mais pas encore confirmé — une QSL à relancer, pas un QSO à faire.', 'dec.colGrid': 'Locator', 'dec.colState': 'État', 'dec.colCountry': 'Pays', 'dec.colBand': 'Bande', 'dec.colMode': 'Mode', 'dec.colStatus': 'Statut', 'dec.stateTip': 'État US', 'dec.wkd': 'Fait', 'dec.bgPota': 'POTA', 'dec.bgGrid': 'LOC', 'dec.bgPfx': 'PFX', 'dec.bgCounty': 'CTY', 'dec.stNew': 'NOUV', 'dec.stBand': 'BANDE', 'dec.stMode': 'MODE', 'dec.stSlot': 'SLOT', 'dec.stCall': 'IND', 'dec.empty': "Aucun decode pour l'instant. Ils arrivent de WSJT-X, JTDX ou MSHV par le lien UDP entrant (Reglages -> UDP).",