fix: digital-mode grouping ignored by the spots already listed

The backend honours the setting: it normalises the log side and the spot's own
mode through the same grouper, so an FT4 spot on a band worked in FT8 reads as
worked. That was not the fault.

Spot statuses are cached per call+band+mode and the cache never expired. Ticking
the box in Settings therefore changed nothing on screen — every spot already
listed kept the answer to the old question, and only new arrivals were judged by
the new rule. The cache is now dropped when settings are saved.

Also: writeUiPref swallowed a failed database write. The interface kept working
from localStorage while the BACKEND — which reads some of these keys, this one
among them — still saw the old value. The two disagreeing in silence is exactly
the shape of this bug, so the failure is now logged.
This commit is contained in:
2026-07-31 12:20:07 +02:00
parent eb40991482
commit c5ac945de0
3 changed files with 20 additions and 5 deletions
+4 -2
View File
@@ -8,7 +8,8 @@
"Playing a recording on the air now says why when it cannot.",
"The play-on-air button is hidden on CW.",
"CW decoder: a station replying at a different speed no longer decodes as a run of dashes, and callsigns are no longer split into single letters by a wide fist.",
"FlexRadio: one table per band for the antennas and the TX power per mode class (phone / CW / digital). Antennas follow the band, power follows the band and the mode; an empty box leaves the power alone."
"FlexRadio: one table per band for the antennas and the TX power per mode class (phone / CW / digital). Antennas follow the band, power follows the band and the mode; an empty box leaves the power alone.",
"Grouping the digital modes into one slot now takes effect on the spots already on screen, instead of only on those arriving afterwards."
],
"fr": [
"FlexRadio : en split, OpsLog reste sur la slice de réception au lieu de suivre l'émission.",
@@ -16,7 +17,8 @@
"L'émission d'un enregistrement indique désormais pourquoi elle échoue.",
"Le bouton d'émission de l'enregistrement est masqué en CW.",
"Décodeur CW : une station qui répond à une autre vitesse ne se décode plus en série de traits, et les indicatifs ne sont plus coupés lettre par lettre par un espacement large.",
"FlexRadio : un seul tableau par bande pour les antennes et la puissance d'émission par type de mode (phonie / CW / numérique). Les antennes suivent la bande, la puissance suit la bande et le mode ; une case vide ne touche pas à la puissance."
"FlexRadio : un seul tableau par bande pour les antennes et la puissance d'émission par type de mode (phonie / CW / numérique). Les antennes suivent la bande, la puissance suit la bande et le mode ; une case vide ne touche pas à la puissance.",
"Le regroupement des modes numériques en un seul créneau s'applique désormais aux spots déjà affichés, et non plus seulement à ceux qui arrivent ensuite."
]
},
{
+8 -1
View File
@@ -6318,7 +6318,14 @@ export default function App() {
<SettingsModal
initialSection={settingsSection}
onClose={() => { setShowSettings(false); setSettingsSection(undefined); }}
onSaved={() => { loadStation(); loadLists(); loadCATCfg(); reloadWk(); refreshManualRecReady(); }}
onSaved={() => {
loadStation(); loadLists(); loadCATCfg(); reloadWk(); refreshManualRecReady();
// Drop the cached spot statuses. They are computed once per
// call+band+mode and never expire, so a rule change in Settings —
// grouping the digital modes into one slot, above all — left every
// spot already on screen showing the answer to the OLD question.
setSpotStatus({});
}}
onMainPaneChanged={(side, v) => { if (side === 'left') setMainPaneLeft(v as MainPaneKind); else setMainPaneRight(v as MainPaneKind); }}
flexAvailable={catState.backend === 'flex'}
icomAvailable={catState.backend === 'icom'}
+8 -2
View File
@@ -5,7 +5,7 @@
// folder (data/) to another machine. These helpers mirror them into the DB
// settings table (ui.* keys, like the grid columns) so the whole setup is
// identical after a copy.
import { GetUIPref, SetUIPref } from '../../wailsjs/go/main/App';
import { GetUIPref, SetUIPref, LogUIError } from '../../wailsjs/go/main/App';
// Keys that must travel with data/ (DB is the portable source of truth; the
// localStorage copy is just a fast, synchronous cache).
@@ -65,5 +65,11 @@ export async function syncPortablePrefs(): Promise<void> {
// Use it everywhere these keys are written instead of localStorage.setItem.
export function writeUiPref(key: string, value: string): void {
try { localStorage.setItem(key, value); } catch { /* quota / private mode */ }
SetUIPref(key, value).catch(() => { /* DB unavailable — the cache still holds it */ });
SetUIPref(key, value).catch((e: any) => {
// The cache still holds it, so the interface behaves — but the BACKEND
// reads some of these keys too (digital-mode grouping decides how the
// cluster judges a slot). A write that reaches localStorage and not the
// database makes the two disagree, and used to do so in silence.
try { LogUIError("ui pref", "could not store " + key + ": " + String(e?.message ?? e), ""); } catch {}
});
}