From b918a8395b60b85dd9e83d5867de0995b1c622d1 Mon Sep 17 00:00:00 2001 From: rouggy Date: Mon, 7 Sep 2026 21:06:10 +0200 Subject: [PATCH] fix(maps): one imagery choice per map, not one for two of them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The world map and the grid-square map shared a single key, so picking satellite imagery to look at grids repainted the main map too, and there was no way to have terrain on one and streets on the other. They are different maps answering different questions, and the imagery that suits one is not the imagery that suits the next. Four keys now, one per map, in lib/mapBase beside the remembered views — named in one place so a rename cannot silently orphan somebody's choice — and portable, so a copied data folder brings them along. The grid map inherits whatever was set under the old shared key rather than being reset to the default: an operator who chose imagery there keeps it. --- changelog.json | 6 ++-- frontend/src/components/FTMapPanel.tsx | 3 +- frontend/src/components/GridSquareMap.tsx | 9 +++-- frontend/src/components/MainMap.tsx | 8 +++-- frontend/src/components/SatellitePanel.tsx | 6 ++-- frontend/src/lib/mapBase.ts | 38 ++++++++++++++++++++++ frontend/src/lib/uiPref.ts | 3 +- 7 files changed, 60 insertions(+), 13 deletions(-) create mode 100644 frontend/src/lib/mapBase.ts diff --git a/changelog.json b/changelog.json index b6caafb..c93c4a5 100644 --- a/changelog.json +++ b/changelog.json @@ -9,7 +9,8 @@ "Settings → Satellites is where the satellite work is set up, and the tab is what you use during a pass. Choose the satellites you follow the way you choose awards — two columns, search, the ones with a frequency plan first — and the tab and the pass list show those and nothing else. The orbital elements move there too: age, fetch, and paste-your-own. None of it is something to be doing while a bird is going over.", "The satellite panel says what a pass actually is. A countdown to AOS, or to LOS once it is up, with a bar showing where in the pass you are; rise, peak and set with their compass directions; distance, altitude and footprint; and whether it is approaching or receding, which is why the frequencies move the way they do. The frequencies keep the corrected figure large and the Doppler shift beside it.", "One satellite list, in one place. Settings → Lists → Satellites is gone: the birds it held by hand had nothing to do with the ones the tracker knew, and the same station kept two lists that drifted apart. The SAT_NAME box on the entry form now offers the satellites you follow — plus anything the old list still held, so nobody's typing is lost. Satellites also moved out of Hardware, where it never belonged, and sits with Operating.", - "PstRotator can point the antenna for satellites too. It handles azimuth and elevation and already knows your controller, so if you run it, choose it in Settings → Satellites and OpsLog sends it the bearing instead of taking the cable itself — two programs on one controller is one too many. Its overlap handling stays its own: a 450° rotator is PstRotator's business, not something two programs should each decide about mid-pass." + "PstRotator can point the antenna for satellites too. It handles azimuth and elevation and already knows your controller, so if you run it, choose it in Settings → Satellites and OpsLog sends it the bearing instead of taking the cable itself — two programs on one controller is one too many. Its overlap handling stays its own: a 450° rotator is PstRotator's business, not something two programs should each decide about mid-pass.", + "Each map keeps its own imagery. The world map and the grid-square map shared one setting, so choosing satellite imagery to look at grids repainted the main map as well, and there was no way to have terrain on one and plain streets on the other. All four — world, grid squares, FT map, satellites — now remember their own choice, and it travels with the data folder like the remembered views. A choice already made for the grid map is carried over, not reset." ], "fr": [ "[NOUVEAU] Satellites. Un nouvel onglet (Outils → Satellites) suit les satellites amateurs : une carte avec l'empreinte de chacun et la trace au sol de celui qui est sélectionné, les prochains passages avec leur élévation maximale, et — pour le satellite en cours — l'azimut, l'élévation et les fréquences de descente et de montée corrigées de l'effet Doppler. Les éléments orbitaux viennent de Celestrak (avec un miroir derrière) et sont conservés sur disque : l'onglet est rempli dès son ouverture, même sans internet. Les éléments d'un satellite qu'aucun flux ne diffuse encore peuvent être collés à la main et survivent à chaque mise à jour. La liste de fréquences fournie couvre les satellites FM et linéaires ainsi que QO-100, dans un fichier que vous pouvez corriger vous-même quand un transpondeur change de mode.", @@ -18,7 +19,8 @@ "Réglages → Satellites, c'est là qu'on configure ; l'onglet, c'est ce qu'on utilise pendant un passage. On choisit les satellites suivis comme on choisit les diplômes — deux colonnes, recherche, ceux qui ont un plan de fréquences d'abord — et l'onglet comme la liste des passages n'affichent que ceux-là. Les éléments orbitaux y passent aussi : âge, récupération, et collage des siens. Rien de tout cela ne se fait pendant qu'un satellite passe.", "Le panneau satellite dit enfin ce qu'est un passage. Un compte à rebours jusqu'à l'AOS, ou jusqu'au LOS une fois qu'il est levé, avec une barre montrant où l'on en est ; lever, culmination et coucher avec leurs directions à la boussole ; distance, altitude et empreinte ; et s'il se rapproche ou s'éloigne, ce qui explique le sens du décalage. Les fréquences gardent la valeur corrigée en grand et le Doppler à côté.", "Une seule liste de satellites, à un seul endroit. Réglages → Listes → Satellites disparaît : les satellites qu'on y saisissait à la main n'avaient aucun rapport avec ceux que connaissait le suivi, et une même station entretenait deux listes qui divergeaient. Le champ SAT_NAME de la saisie propose désormais les satellites que vous suivez — plus ce que l'ancienne liste contenait encore, pour ne rien perdre. Satellites quitte aussi Matériel, où il n'avait rien à faire, pour rejoindre Opération.", - "PstRotator peut aussi pointer l'antenne pour les satellites. Il gère azimut et élévation et connaît déjà votre contrôleur : si vous le faites tourner, choisissez-le dans Réglages → Satellites et OpsLog lui envoie le cap au lieu de prendre le câble lui-même — deux programmes sur un contrôleur, c'est un de trop. Le recouvrement reste son affaire : un rotor 450°, c'est à PstRotator d'en décider, pas à deux programmes en plein passage." + "PstRotator peut aussi pointer l'antenne pour les satellites. Il gère azimut et élévation et connaît déjà votre contrôleur : si vous le faites tourner, choisissez-le dans Réglages → Satellites et OpsLog lui envoie le cap au lieu de prendre le câble lui-même — deux programmes sur un contrôleur, c'est un de trop. Le recouvrement reste son affaire : un rotor 450°, c'est à PstRotator d'en décider, pas à deux programmes en plein passage.", + "Chaque carte garde son propre fond. La carte principale et celle des carrés partageaient un seul réglage : choisir la vue satellite pour regarder les carrés repeignait aussi la carte principale, et il n'y avait aucun moyen d'avoir le relief sur l'une et les rues sur l'autre. Les quatre — principale, carrés, FT map, satellites — retiennent désormais leur propre choix, qui suit le dossier de données comme les positions mémorisées. Un choix déjà fait pour la carte des carrés est repris, pas réinitialisé." ] }, { diff --git a/frontend/src/components/FTMapPanel.tsx b/frontend/src/components/FTMapPanel.tsx index 7d1e1ba..a3a6644 100644 --- a/frontend/src/components/FTMapPanel.tsx +++ b/frontend/src/components/FTMapPanel.tsx @@ -6,6 +6,7 @@ import { BASEMAPS, type BasemapKey } from '@/components/MainMap'; import { cn } from '@/lib/utils'; import { useI18n } from '@/lib/i18n'; import { loadMapView, saveMapView, MAP_VIEW_FT } from '@/lib/mapView'; +import { loadMapBase, saveMapBase, MAP_BASE_FT } from '@/lib/mapBase'; // FT Map — the live decode feed as geography: every station decoded in the // last half hour, an arc from the operator's own square to theirs, coloured by @@ -128,7 +129,7 @@ export function FTMapPanel({ decodes, myGrid, onSelect, onCall }: { }; baseRef.current = L.tileLayer(bm.url, { ...opts, attribution: bm.attr, subdomains: bm.subdomains ?? 'abc' }).addTo(m); if (bm.labelsUrl) labelsRef.current = L.tileLayer(bm.labelsUrl, opts).addTo(m); - localStorage.setItem('opslog.ftmapBase', basemap); + saveMapBase(MAP_BASE_FT, basemap); }, [basemap]); // The arcs, redrawn when the decode list changes. Newest last so they paint diff --git a/frontend/src/components/GridSquareMap.tsx b/frontend/src/components/GridSquareMap.tsx index 972d357..200cdba 100644 --- a/frontend/src/components/GridSquareMap.tsx +++ b/frontend/src/components/GridSquareMap.tsx @@ -6,7 +6,8 @@ import { GridSquares } from '../../wailsjs/go/main/App'; import { gridSquareBounds, gridToLatLon } from '@/lib/maidenhead'; import { useI18n } from '@/lib/i18n'; import { cn } from '@/lib/utils'; -import { BASEMAPS, addBasemap, loadBasemap, type BasemapKey } from '@/components/MainMap'; +import { BASEMAPS, addBasemap, type BasemapKey } from '@/components/MainMap'; +import { loadMapBase, saveMapBase, MAP_BASE_GRIDS, MAP_BASE_WORLD } from '@/lib/mapBase'; import { writeUiPref } from '@/lib/uiPref'; import { loadMapView, saveMapView, MAP_VIEW_GRIDS } from '@/lib/mapView'; @@ -86,7 +87,9 @@ export function GridSquareMap({ myGrid, className }: { myGrid?: string; classNam () => (SCOPES.some((s) => s.key === localStorage.getItem(SCOPE_KEY)) ? (localStorage.getItem(SCOPE_KEY) as ScopeKey) : 'DIGI')); - const [basemap, setBasemap] = useState(loadBasemap); + // This map's own imagery. It shared the world map's key until they were + // separated, so a choice made back then is inherited rather than reset. + const [basemap, setBasemap] = useState(() => loadMapBase(MAP_BASE_GRIDS, 'light', MAP_BASE_WORLD)); const [confColour, setConfColour] = useState(() => localStorage.getItem(COL_CONFIRMED_KEY) ?? ''); const [workedColour, setWorkedColour] = useState(() => localStorage.getItem(COL_WORKED_KEY) ?? ''); // Repaint the squares when the THEME changes, not the basemap: the fills come @@ -253,7 +256,7 @@ export function GridSquareMap({ myGrid, className }: { myGrid?: string; classNam