From 2092e2ca6fc853d97a84a8fd9bd33c3c3892d46a Mon Sep 17 00:00:00 2001 From: Michael R Wheeley Date: Thu, 2 Apr 2026 18:50:34 -0700 Subject: [PATCH 01/14] add station altitude, minimum elevation settings pass tle data from useSatellites.js --- src/App.jsx | 2 +- src/components/SettingsPanel.jsx | 76 +++++++++++++++++++++++++++++++- src/hooks/useSatellites.js | 10 +++-- 3 files changed, 82 insertions(+), 6 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 74dca8ee..41c3099d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -320,7 +320,7 @@ const App = () => { const propagation = usePropagation(config.location, dxLocation, config.propagation); const mySpots = useMySpots(config.callsign); - const satellites = useSatellites(config.location); + const satellites = useSatellites(config.location, config.satellite); const localWeather = useWeather(config.location, config.allUnits); const dxWeather = useWeather(dxLocation, config.allUnits); const localAlerts = useWeatherAlerts(config.location); diff --git a/src/components/SettingsPanel.jsx b/src/components/SettingsPanel.jsx index fccd37ac..5d636c2a 100644 --- a/src/components/SettingsPanel.jsx +++ b/src/components/SettingsPanel.jsx @@ -49,6 +49,8 @@ export const SettingsPanel = ({ const [gridSquare, setGridSquare] = useState(config?.locator || ''); const [lat, setLat] = useState(config?.location?.lat ?? 0); const [lon, setLon] = useState(config?.location?.lon ?? 0); + const [stationAlt, setStationAlt] = useState(config?.location?.stationAlt ?? 100); + const [minElev, setMinElev] = useState(config?.satellite?.minElev ?? 5.0); const [layout, setLayout] = useState(config?.layout || 'modern'); const [mouseZoom, setMouseZoom] = useState(config?.mouseZoom || 50); const [timezone, setTimezone] = useState(config?.timezone || ''); @@ -178,6 +180,8 @@ export const SettingsPanel = ({ setheaderSize(config.headerSize || 1.0); setLat(config.location?.lat ?? 0); setLon(config.location?.lon ?? 0); + setStationAlt(config.location?.stationAlt ?? 100); + setMinElev(config.satellite?.minElev ?? 5.0); setLayout(config.layout || 'modern'); setMouseZoom(config.mouseZoom || 50); setTimezone(config.timezone || ''); @@ -417,7 +421,8 @@ export const SettingsPanel = ({ headerSize: headerSize, swapHeaderClocks, showMutualReception, - location: { lat: parseFloat(lat), lon: parseFloat(lon) }, + location: { lat: parseFloat(lat) || 0, lon: parseFloat(lon) || 0, stationAlt: parseInt(stationAlt) || 100 }, + satellite: { minElev: parseFloat(minElev) || 5.0 }, theme, customTheme, layout, @@ -3294,6 +3299,75 @@ export const SettingsPanel = ({ Footprints + + {/* station altitude and minimum elevation inputs */} +
+
+ + setStationAlt(parseInt(e.target.value) || 100)} + style={{ + width: '100%', + padding: '10px', + background: 'var(--bg-tertiary)', + border: '1px solid var(--border-color)', + borderRadius: '6px', + color: 'var(--text-primary)', + fontSize: '14px', + fontFamily: 'JetBrains Mono, monospace', + boxSizing: 'border-box', + }} + /> +
+
+ + setMinElev(parseFloat(e.target.value) || 5.0)} + style={{ + width: '100%', + padding: '10px', + background: 'var(--bg-tertiary)', + border: '1px solid var(--border-color)', + borderRadius: '6px', + color: 'var(--text-primary)', + fontSize: '14px', + fontFamily: 'JetBrains Mono, monospace', + boxSizing: 'border-box', + }} + /> +
+
+ {/* Lead Time Slider WIP
+ + +
- + +
${t('station.settings.satellites.latitude')}:${sat.lat.toFixed(2)}°
${t('station.settings.satellites.longitude')}:${sat.lon.toFixed(2)}°
${t('station.settings.satellites.speed')}:${speedStr}
${t('station.settings.satellites.altitude')}:${altitudeStr}
${t('station.settings.satellites.speed')}:${speedStr}
+ + + ${ @@ -279,17 +286,24 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con : `` } - - ${sat.downlink ? `` : ''} - ${sat.uplink ? `` : ''} - ${sat.tone ? `` : ''} -
${t('station.settings.satellites.azimuth_elevation')}:${sat.azimuth}° / ${sat.elevation}°
${t('station.settings.satellites.mode')}:${sat.mode || 'N/A'}
${t('station.settings.satellites.downlink')}:${sat.downlink}
${t('station.settings.satellites.uplink')}:${sat.uplink}
${t('station.settings.satellites.tone')}:${sat.tone}
${t('station.settings.satellites.status')}: ${isVisible ? `${t('station.settings.satellites.visible')}` : `${t('station.settings.satellites.belowHorizon')}`}
- ${sat.notes ? `
${sat.notes}
` : ''} + + + + + + ${sat.downlink ? `` : ''} + ${sat.uplink ? `` : ''} + ${sat.tone ? `` : ''} +
${t('station.settings.satellites.mode')}:${sat.mode || 'N/A'}
${t('station.settings.satellites.downlink')}:${sat.downlink}
${t('station.settings.satellites.uplink')}:${sat.uplink}
${t('station.settings.satellites.tone')}:${sat.tone}
+ + + + ${sat.notes ? `
${sat.notes}
` : ''} `; }) From 61c147810464567fa99aa4bddbde13cd6d2483fa Mon Sep 17 00:00:00 2001 From: Michael R Wheeley Date: Fri, 3 Apr 2026 14:40:27 -0700 Subject: [PATCH 06/14] minor correction to input variables --- src/components/SettingsPanel.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/SettingsPanel.jsx b/src/components/SettingsPanel.jsx index eabc9f03..34b58588 100644 --- a/src/components/SettingsPanel.jsx +++ b/src/components/SettingsPanel.jsx @@ -3386,7 +3386,7 @@ export const SettingsPanel = ({ type="number" step="1" value={isNaN(stationAlt) ? '' : stationAlt} - onChange={(e) => setStationAlt(parseInt(e.target.value) || 100)} + onChange={(e) => setStationAlt(e.target.valueAsNumber ?? 100)} style={{ width: '100%', padding: '10px', @@ -3418,7 +3418,7 @@ export const SettingsPanel = ({ min="-89.0" max="89.0" value={isNaN(minElev) ? '' : minElev} - onChange={(e) => setMinElev(parseFloat(e.target.value) || 5.0)} + onChange={(e) => setMinElev(e.target.valueAsNumber ?? 5.0)} style={{ width: '100%', padding: '10px', From 2df9780c113b077fe2008b40416a835f35d9ea27 Mon Sep 17 00:00:00 2001 From: Michael R Wheeley Date: Sat, 4 Apr 2026 10:01:38 -0700 Subject: [PATCH 07/14] style highliting green background when satellite is visible --- src/plugins/layers/useSatelliteLayer.js | 65 +++++++++++++++++-------- 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/src/plugins/layers/useSatelliteLayer.js b/src/plugins/layers/useSatelliteLayer.js index 0a916a5d..20b39395 100644 --- a/src/plugins/layers/useSatelliteLayer.js +++ b/src/plugins/layers/useSatelliteLayer.js @@ -197,7 +197,7 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con @@ -258,47 +258,70 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con return `
- ${sat.name} + ${sat.name}
-
- - - - +
${t('station.settings.satellites.latitude')}:${sat.lat.toFixed(2)}°
${t('station.settings.satellites.longitude')}:${sat.lon.toFixed(2)}°
${t('station.settings.satellites.altitude')}:${altitudeStr}
${t('station.settings.satellites.speed')}:${speedStr}
+ + + + + + + + + + + + + + + +
${t('station.settings.satellites.latitude')}:${sat.lat.toFixed(2)}°
${t('station.settings.satellites.longitude')}:${sat.lon.toFixed(2)}°
${t('station.settings.satellites.altitude')}:${altitudeStr}
${t('station.settings.satellites.speed')}:${speedStr}
- - +
${t('station.settings.satellites.azimuth_elevation')}:${sat.azimuth}° / ${sat.elevation}°
+ ${ isVisible ? ` - - - + + + + + + + + + + + + ` : `` } - - + + +
${t('station.settings.satellites.azimuth_elevation')}:${sat.azimuth}° / ${sat.elevation}°
${t('station.settings.satellites.range')}:${(sat.range * (isMetric ? 1 : km_to_miles_factor)).toFixed(0)} ${distanceUnitsStr}
${t('station.settings.satellites.rangeRate')}:${(sat.rangeRate * (isMetric ? 1 : km_to_miles_factor)).toFixed(2)} ${rangeRateUnitsStr}
${t('station.settings.satellites.dopplerFactor')}:${sat.dopplerFactor.toFixed(7)}
${t('station.settings.satellites.range')}:${(sat.range * (isMetric ? 1 : km_to_miles_factor)).toFixed(0)} ${distanceUnitsStr}
${t('station.settings.satellites.rangeRate')}:${(sat.rangeRate * (isMetric ? 1 : km_to_miles_factor)).toFixed(2)} ${rangeRateUnitsStr}
${t('station.settings.satellites.dopplerFactor')}:${sat.dopplerFactor.toFixed(7)}
${t('station.settings.satellites.status')}: - ${isVisible ? `${t('station.settings.satellites.visible')}` : `${t('station.settings.satellites.belowHorizon')}`} -
${t('station.settings.satellites.status')}:${isVisible ? `${t('station.settings.satellites.visible')}` : `${t('station.settings.satellites.belowHorizon')}`}
- - - ${sat.downlink ? `` : ''} - ${sat.uplink ? `` : ''} - ${sat.tone ? `` : ''} +
${t('station.settings.satellites.mode')}:${sat.mode || 'N/A'}
${t('station.settings.satellites.downlink')}:${sat.downlink}
${t('station.settings.satellites.uplink')}:${sat.uplink}
${t('station.settings.satellites.tone')}:${sat.tone}
+ + + + + ${sat.downlink ? `` : ''} + ${sat.uplink ? `` : ''} + ${sat.tone ? `` : ''}
${t('station.settings.satellites.mode')}:${sat.mode || 'N/A'}
${t('station.settings.satellites.downlink')}:${sat.downlink}
${t('station.settings.satellites.uplink')}:${sat.uplink}
${t('station.settings.satellites.tone')}:${sat.tone}
From a5fd0ac1a0d8fa64d613a67105489876e9bab8d8 Mon Sep 17 00:00:00 2001 From: Michael R Wheeley Date: Sun, 5 Apr 2026 12:10:45 -0700 Subject: [PATCH 08/14] fix table within a table html color changes replace ?? with || incase of NaN minElev default consistency to 5.0 restrict minElev to -5 to 89 --- src/components/SettingsPanel.jsx | 20 ++--- src/plugins/layers/useSatelliteLayer.js | 101 ++++++++++++------------ 2 files changed, 59 insertions(+), 62 deletions(-) diff --git a/src/components/SettingsPanel.jsx b/src/components/SettingsPanel.jsx index 34b58588..40ff2a53 100644 --- a/src/components/SettingsPanel.jsx +++ b/src/components/SettingsPanel.jsx @@ -47,10 +47,10 @@ export const SettingsPanel = ({ const [swapHeaderClocks, setSwapHeaderClocks] = useState(config?.swapHeaderClocks || false); const [showMutualReception, setShowMutualReception] = useState(config?.showMutualReception ?? true); const [gridSquare, setGridSquare] = useState(config?.locator || ''); - const [lat, setLat] = useState(config?.location?.lat ?? 0); - const [lon, setLon] = useState(config?.location?.lon ?? 0); - const [stationAlt, setStationAlt] = useState(config?.location?.stationAlt ?? 100); - const [minElev, setMinElev] = useState(config?.satellite?.minElev ?? 5.0); + const [lat, setLat] = useState(config?.location?.lat || 0); + const [lon, setLon] = useState(config?.location?.lon || 0); + const [stationAlt, setStationAlt] = useState(config?.location?.stationAlt || 100); + const [minElev, setMinElev] = useState(config?.satellite?.minElev || 5.0); const [layout, setLayout] = useState(config?.layout || 'modern'); const [mouseZoom, setMouseZoom] = useState(config?.mouseZoom || 50); const [timezone, setTimezone] = useState(config?.timezone || ''); @@ -179,10 +179,10 @@ export const SettingsPanel = ({ if (config) { setCallsign(config.callsign || ''); setheaderSize(config.headerSize || 1.0); - setLat(config.location?.lat ?? 0); - setLon(config.location?.lon ?? 0); - setStationAlt(config.location?.stationAlt ?? 100); - setMinElev(config.satellite?.minElev ?? 5.0); + setLat(config.location?.lat || 0); + setLon(config.location?.lon || 0); + setStationAlt(config.location?.stationAlt || 100); + setMinElev(config.satellite?.minElev || 5.0); setLayout(config.layout || 'modern'); setMouseZoom(config.mouseZoom || 50); setTimezone(config.timezone || ''); @@ -3415,10 +3415,10 @@ export const SettingsPanel = ({ setMinElev(e.target.valueAsNumber ?? 5.0)} + onChange={(e) => setMinElev(isNaN(e.target.valueAsNumber) ? 5.0 : e.target.valueAsNumber)} style={{ width: '100%', padding: '10px', diff --git a/src/plugins/layers/useSatelliteLayer.js b/src/plugins/layers/useSatelliteLayer.js index 20b39395..8359add1 100644 --- a/src/plugins/layers/useSatelliteLayer.js +++ b/src/plugins/layers/useSatelliteLayer.js @@ -79,7 +79,7 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con az = lookAngles.azimuth * (180 / Math.PI); el = lookAngles.elevation * (180 / Math.PI); range = lookAngles.rangeSat; - isVisible = el >= (config?.satellite?.minElev || 0); // visible only if above minimum elevation + isVisible = el >= (config?.satellite?.minElev || 5.0); // visible only if above minimum elevation } const minutesToPredict = config?.leadTimeMins || 45; @@ -129,9 +129,9 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con position: 'absolute', width: '260px', backgroundColor: 'rgba(0, 15, 15, 0.95)', - color: '#00ffff', + color: '#0ff', borderRadius: '4px', - border: '1px solid #00ffff', + border: '1px solid #0ff', zIndex: '1000', fontFamily: 'monospace', pointerEvents: 'auto', @@ -190,8 +190,8 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con const titleBar = `
- + padding: 8px 10px; border-bottom: 1px solid #044; background: rgba(0,40,40,0.6);"> + 🛰 ${activeSats.length} ${activeSats.length !== 1 ? t('station.settings.satellites.name_plural') : t('station.settings.satellites.name')} @@ -256,77 +256,74 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con let altitudeStr = `${altitude.toLocaleString()} ${distanceUnitsStr}`; return ` -
+
- ${sat.name} + ${sat.name} + style="background:none; border:none; color: #f44; cursor:pointer; font-weight:bold; font-size:20px; padding: 0 5px;">✕
-
- - - + + + - - - + + + - - - + + + - - - + + + -
${t('station.settings.satellites.latitude')}:${sat.lat.toFixed(2)}°
${t('station.settings.satellites.latitude')}:${sat.lat.toFixed(2)}°
${t('station.settings.satellites.longitude')}:${sat.lon.toFixed(2)}°
${t('station.settings.satellites.longitude')}:${sat.lon.toFixed(2)}°
${t('station.settings.satellites.altitude')}:${altitudeStr}
${t('station.settings.satellites.altitude')}:${altitudeStr}
${t('station.settings.satellites.speed')}:${speedStr}
${t('station.settings.satellites.speed')}:${speedStr}
- - + + + + ${ isVisible ? ` - - - + + + - - - + + + - - - + + + ` : `` } - - - + + + -
${t('station.settings.satellites.azimuth_elevation')}:${sat.azimuth}° / ${sat.elevation}°
${t('station.settings.satellites.azimuth_elevation')}:${sat.azimuth}° / ${sat.elevation}°
${t('station.settings.satellites.range')}:${(sat.range * (isMetric ? 1 : km_to_miles_factor)).toFixed(0)} ${distanceUnitsStr}
${t('station.settings.satellites.range')}:${(sat.range * (isMetric ? 1 : km_to_miles_factor)).toFixed(0)} ${distanceUnitsStr}
${t('station.settings.satellites.rangeRate')}:${(sat.rangeRate * (isMetric ? 1 : km_to_miles_factor)).toFixed(2)} ${rangeRateUnitsStr}
${t('station.settings.satellites.rangeRate')}:${(sat.rangeRate * (isMetric ? 1 : km_to_miles_factor)).toFixed(2)} ${rangeRateUnitsStr}
${t('station.settings.satellites.dopplerFactor')}:${sat.dopplerFactor.toFixed(7)}
${t('station.settings.satellites.dopplerFactor')}:${sat.dopplerFactor.toFixed(7)}
${t('station.settings.satellites.status')}:${isVisible ? `${t('station.settings.satellites.visible')}` : `${t('station.settings.satellites.belowHorizon')}`}
${t('station.settings.satellites.status')}:${isVisible ? `${t('station.settings.satellites.visible')}` : `${t('station.settings.satellites.belowHorizon')}`}
- - - - + + + - ${sat.downlink ? `` : ''} - ${sat.uplink ? `` : ''} - ${sat.tone ? `` : ''} -
${t('station.settings.satellites.mode')}:${sat.mode || 'N/A'}
${t('station.settings.satellites.mode')}:${sat.mode || 'N/A'}
${t('station.settings.satellites.downlink')}:${sat.downlink}
${t('station.settings.satellites.uplink')}:${sat.uplink}
${t('station.settings.satellites.tone')}:${sat.tone}
+ ${sat.downlink ? `${t('station.settings.satellites.downlink')}:${sat.downlink}` : ''} + ${sat.uplink ? `${t('station.settings.satellites.uplink')}:${sat.uplink}` : ''} + ${sat.tone ? `${t('station.settings.satellites.tone')}:${sat.tone}` : ''} - ${sat.notes ? `
${sat.notes}
` : ''} + ${sat.notes ? `
${sat.notes}
` : ''}
`; }) @@ -357,7 +354,7 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con const EARTH_RADIUS = 6371; const centralAngle = Math.acos(EARTH_RADIUS / (EARTH_RADIUS + sat.alt)); const footprintRadiusMeters = centralAngle * EARTH_RADIUS * 1000; - const footColor = sat.isVisible === true ? '#00ff00' : '#00ffff'; + const footColor = sat.isVisible === true ? '#00ff00' : '#0ff'; replicatePoint(sat.lat, sat.lon).forEach((pos) => { window.L.circle(pos, { @@ -379,7 +376,7 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con for (let i = 0; i < coords.length - 1; i++) { const fade = i / coords.length; window.L.polyline([coords[i], coords[i + 1]], { - color: '#00ffff', + color: '#0ff', weight: 6, opacity: fade * 0.3 * globalOpacity, lineCap: 'round', @@ -395,7 +392,7 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con } } else { window.L.polyline(coords, { - color: '#00ffff', + color: '#0ff', weight: 1, opacity: 0.15 * globalOpacity, dashArray: '5, 10', @@ -424,8 +421,8 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con icon: window.L.divIcon({ className: 'sat-marker', html: `
-
🛰
-
${sat.name}
+
🛰
+
${sat.name}
`, iconSize: [80, 50], iconAnchor: [40, 25], From ffaa64f12bff40aae91e56f3f11ffc875f6369ce Mon Sep 17 00:00:00 2001 From: Michael R Wheeley Date: Mon, 6 Apr 2026 11:00:32 -0700 Subject: [PATCH 09/14] remove # hardcoded colors, replace with rgba(), modify opacity on selected colors --- src/plugins/layers/useSatelliteLayer.js | 64 ++++++++++++------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/plugins/layers/useSatelliteLayer.js b/src/plugins/layers/useSatelliteLayer.js index 8359add1..fc92eddb 100644 --- a/src/plugins/layers/useSatelliteLayer.js +++ b/src/plugins/layers/useSatelliteLayer.js @@ -129,9 +129,9 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con position: 'absolute', width: '260px', backgroundColor: 'rgba(0, 15, 15, 0.95)', - color: '#0ff', + color: 'rgba(0, 255, 255, 1)', borderRadius: '4px', - border: '1px solid #0ff', + border: '1px solid rgba(0, 255, 255, 1)', zIndex: '1000', fontFamily: 'monospace', pointerEvents: 'auto', @@ -190,14 +190,14 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con const titleBar = `
- + padding: 8px 10px; border-bottom: 1px solid rgba(0, 68, 68, 1); background: rgba(0,40,40,0.6);"> + 🛰 ${activeSats.length} ${activeSats.length !== 1 ? t('station.settings.satellites.name_plural') : t('station.settings.satellites.name')} @@ -225,11 +225,11 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con const clearAllBtn = `
- ${t('station.settings.satellites.dragTitle')} + ${t('station.settings.satellites.dragTitle')}
`; @@ -256,34 +256,34 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con let altitudeStr = `${altitude.toLocaleString()} ${distanceUnitsStr}`; return ` -
+
- ${sat.name} + ${sat.name} + style="background:none; border:none; color: rgba(255, 68, 68, 1); cursor:pointer; font-weight:bold; font-size:20px; padding: 0 5px;">✕
- + - + - + - + - + @@ -291,15 +291,15 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con ${ isVisible ? ` - + - + - + @@ -307,23 +307,23 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con : `` } - + - + - + - ${sat.downlink ? `` : ''} - ${sat.uplink ? `` : ''} - ${sat.tone ? `` : ''} + ${sat.downlink ? `` : ''} + ${sat.uplink ? `` : ''} + ${sat.tone ? `` : ''}
${t('station.settings.satellites.latitude')}: ${sat.lat.toFixed(2)}°
${t('station.settings.satellites.longitude')}: ${sat.lon.toFixed(2)}°
${t('station.settings.satellites.altitude')}: ${altitudeStr}
${t('station.settings.satellites.speed')}: ${speedStr}
${t('station.settings.satellites.azimuth_elevation')}: ${sat.azimuth}° / ${sat.elevation}°
${t('station.settings.satellites.range')}: ${(sat.range * (isMetric ? 1 : km_to_miles_factor)).toFixed(0)} ${distanceUnitsStr}
${t('station.settings.satellites.rangeRate')}: ${(sat.rangeRate * (isMetric ? 1 : km_to_miles_factor)).toFixed(2)} ${rangeRateUnitsStr}
${t('station.settings.satellites.dopplerFactor')}: ${sat.dopplerFactor.toFixed(7)}
${t('station.settings.satellites.status')}: ${isVisible ? `${t('station.settings.satellites.visible')}` : `${t('station.settings.satellites.belowHorizon')}`}
${t('station.settings.satellites.mode')}:${sat.mode || 'N/A'}${sat.mode || 'N/A'}
${t('station.settings.satellites.downlink')}:${sat.downlink}
${t('station.settings.satellites.uplink')}:${sat.uplink}
${t('station.settings.satellites.tone')}:${sat.tone}
${t('station.settings.satellites.downlink')}:${sat.downlink}
${t('station.settings.satellites.uplink')}:${sat.uplink}
${t('station.settings.satellites.tone')}:${sat.tone}
- ${sat.notes ? `
${sat.notes}
` : ''} + ${sat.notes ? `
${sat.notes}
` : ''}
`; }) @@ -354,7 +354,7 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con const EARTH_RADIUS = 6371; const centralAngle = Math.acos(EARTH_RADIUS / (EARTH_RADIUS + sat.alt)); const footprintRadiusMeters = centralAngle * EARTH_RADIUS * 1000; - const footColor = sat.isVisible === true ? '#00ff00' : '#0ff'; + const footColor = sat.isVisible === true ? 'rgba(0, 255, 0, 1)' : 'rgba(0, 255, 255, 1)'; replicatePoint(sat.lat, sat.lon).forEach((pos) => { window.L.circle(pos, { @@ -376,14 +376,14 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con for (let i = 0; i < coords.length - 1; i++) { const fade = i / coords.length; window.L.polyline([coords[i], coords[i + 1]], { - color: '#0ff', + color: 'rgba(0, 255, 255, 1)', weight: 6, opacity: fade * 0.3 * globalOpacity, lineCap: 'round', interactive: false, }).addTo(layerGroupRef.current); window.L.polyline([coords[i], coords[i + 1]], { - color: '#ffffff', + color: 'rgba(255, 255, 255, 1)fff', weight: 2, opacity: fade * globalOpacity, lineCap: 'round', @@ -392,7 +392,7 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con } } else { window.L.polyline(coords, { - color: '#0ff', + color: 'rgba(0, 255, 255, 1)', weight: 1, opacity: 0.15 * globalOpacity, dashArray: '5, 10', @@ -405,7 +405,7 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con const leadCoords = sat.leadTrack.map((p) => [p[0], p[1]]); replicatePath(leadCoords).forEach((lCoords) => { window.L.polyline(lCoords, { - color: '#ffff00', + color: 'rgba(255, 255, 255, 1)f00', weight: 3, opacity: 0.8 * globalOpacity, dashArray: '8, 12', @@ -421,8 +421,8 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con icon: window.L.divIcon({ className: 'sat-marker', html: `
-
🛰
-
${sat.name}
+
🛰
+
${sat.name}
`, iconSize: [80, 50], iconAnchor: [40, 25], From 4ec9e6bef7106d361788d31a9bf02d9f32db75ef Mon Sep 17 00:00:00 2001 From: Michael R Wheeley Date: Mon, 6 Apr 2026 18:13:30 -0700 Subject: [PATCH 10/14] must fix per https://github.com/accius/openhamclock/pull/877 --- src/components/SettingsPanel.jsx | 4 +++- src/hooks/useSatellites.js | 2 +- src/plugins/layers/useSatelliteLayer.js | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/SettingsPanel.jsx b/src/components/SettingsPanel.jsx index 40ff2a53..d7cf074d 100644 --- a/src/components/SettingsPanel.jsx +++ b/src/components/SettingsPanel.jsx @@ -3386,7 +3386,9 @@ export const SettingsPanel = ({ type="number" step="1" value={isNaN(stationAlt) ? '' : stationAlt} - onChange={(e) => setStationAlt(e.target.valueAsNumber ?? 100)} + onChange={(e) => + setStationAlt(isNaN(e.target.valueAsNumber) ? 100 : e.target.valueAsNumber) + } style={{ width: '100%', padding: '10px', diff --git a/src/hooks/useSatellites.js b/src/hooks/useSatellites.js index d1ad387f..20aa0c1d 100644 --- a/src/hooks/useSatellites.js +++ b/src/hooks/useSatellites.js @@ -82,7 +82,7 @@ export const useSatellites = (observerLocation, satelliteConfig) => { const elevation = satellite.radiansToDegrees(lookAngles.elevation); const rangeSat = lookAngles.rangeSat; - const isVisible = elevation >= satelliteConfig.minElev; // visible only if above minimum elevation + const isVisible = elevation >= (satelliteConfig?.minElev || 5.0); // visible only if above minimum elevation // Calculate range-rate and doppler factor, only if satellite is visible let dopplerFactor = 1; diff --git a/src/plugins/layers/useSatelliteLayer.js b/src/plugins/layers/useSatelliteLayer.js index fc92eddb..ec6edf66 100644 --- a/src/plugins/layers/useSatelliteLayer.js +++ b/src/plugins/layers/useSatelliteLayer.js @@ -383,7 +383,7 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con interactive: false, }).addTo(layerGroupRef.current); window.L.polyline([coords[i], coords[i + 1]], { - color: 'rgba(255, 255, 255, 1)fff', + color: 'rgba(255, 255, 255, 1)', weight: 2, opacity: fade * globalOpacity, lineCap: 'round', @@ -405,7 +405,7 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con const leadCoords = sat.leadTrack.map((p) => [p[0], p[1]]); replicatePath(leadCoords).forEach((lCoords) => { window.L.polyline(lCoords, { - color: 'rgba(255, 255, 255, 1)f00', + color: 'rgba(255, 255, 0, 1)', weight: 3, opacity: 0.8 * globalOpacity, dashArray: '8, 12', From 74f8d02639ddd76ad15cc80a2b72791e725bca4a Mon Sep 17 00:00:00 2001 From: Michael R Wheeley Date: Mon, 6 Apr 2026 18:22:41 -0700 Subject: [PATCH 11/14] settingsPanel.jsx ?? vs || --- src/components/SettingsPanel.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/SettingsPanel.jsx b/src/components/SettingsPanel.jsx index d7cf074d..f9373433 100644 --- a/src/components/SettingsPanel.jsx +++ b/src/components/SettingsPanel.jsx @@ -47,10 +47,10 @@ export const SettingsPanel = ({ const [swapHeaderClocks, setSwapHeaderClocks] = useState(config?.swapHeaderClocks || false); const [showMutualReception, setShowMutualReception] = useState(config?.showMutualReception ?? true); const [gridSquare, setGridSquare] = useState(config?.locator || ''); - const [lat, setLat] = useState(config?.location?.lat || 0); - const [lon, setLon] = useState(config?.location?.lon || 0); - const [stationAlt, setStationAlt] = useState(config?.location?.stationAlt || 100); - const [minElev, setMinElev] = useState(config?.satellite?.minElev || 5.0); + const [lat, setLat] = useState(config?.location?.lat ?? 0); + const [lon, setLon] = useState(config?.location?.lon ?? 0); + const [stationAlt, setStationAlt] = useState(config?.location?.stationAlt ?? 100); + const [minElev, setMinElev] = useState(config?.satellite?.minElev ?? 5.0); const [layout, setLayout] = useState(config?.layout || 'modern'); const [mouseZoom, setMouseZoom] = useState(config?.mouseZoom || 50); const [timezone, setTimezone] = useState(config?.timezone || ''); From 7658dabf04e230557cd0f8988ad16f4f44423f3e Mon Sep 17 00:00:00 2001 From: Michael R Wheeley Date: Tue, 14 Apr 2026 12:03:29 -0700 Subject: [PATCH 12/14] forward copy satellite color style changes --- src/plugins/layers/useSatelliteLayer.js | 48 ++++++++++++------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/plugins/layers/useSatelliteLayer.js b/src/plugins/layers/useSatelliteLayer.js index ec6edf66..4872ea16 100644 --- a/src/plugins/layers/useSatelliteLayer.js +++ b/src/plugins/layers/useSatelliteLayer.js @@ -128,14 +128,14 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con Object.assign(win.style, { position: 'absolute', width: '260px', - backgroundColor: 'rgba(0, 15, 15, 0.95)', + backgroundColor: 'var(--bg-primary)', color: 'rgba(0, 255, 255, 1)', borderRadius: '4px', border: '1px solid rgba(0, 255, 255, 1)', zIndex: '1000', fontFamily: 'monospace', pointerEvents: 'auto', - boxShadow: '0 0 15px rgba(0,0,0,0.7)', + boxShadow: '0 0 15px rgba(0, 0, 0, 0.7)', cursor: 'default', overflow: 'hidden', }); @@ -190,14 +190,14 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con const titleBar = `
- + padding: 8px 10px; border-bottom: 1px solid var(--border-color); background: var(--bg-tertiary);"> + 🛰 ${activeSats.length} ${activeSats.length !== 1 ? t('station.settings.satellites.name_plural') : t('station.settings.satellites.name')} @@ -225,11 +225,11 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con const clearAllBtn = `
- ${t('station.settings.satellites.dragTitle')} + ${t('station.settings.satellites.dragTitle')}
`; @@ -258,32 +258,32 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con return `
- ${sat.name} + ${sat.name} + style="background:none; border:none; color: var(--accent-red); cursor:pointer; font-weight:bold; font-size:20px; padding: 0 5px;">✕
- + - + - + - + - + @@ -291,15 +291,15 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con ${ isVisible ? ` - + - + - + @@ -307,23 +307,23 @@ export const useLayer = ({ map, enabled, satellites, setSatellites, opacity, con : `` } - + - + - + - ${sat.downlink ? `` : ''} - ${sat.uplink ? `` : ''} - ${sat.tone ? `` : ''} + ${sat.downlink ? `` : ''} + ${sat.uplink ? `` : ''} + ${sat.tone ? `` : ''}
${t('station.settings.satellites.latitude')}: ${sat.lat.toFixed(2)}°
${t('station.settings.satellites.longitude')}: ${sat.lon.toFixed(2)}°
${t('station.settings.satellites.altitude')}: ${altitudeStr}
${t('station.settings.satellites.speed')}: ${speedStr}
${t('station.settings.satellites.azimuth_elevation')}: ${sat.azimuth}° / ${sat.elevation}°
${t('station.settings.satellites.range')}: ${(sat.range * (isMetric ? 1 : km_to_miles_factor)).toFixed(0)} ${distanceUnitsStr}
${t('station.settings.satellites.rangeRate')}: ${(sat.rangeRate * (isMetric ? 1 : km_to_miles_factor)).toFixed(2)} ${rangeRateUnitsStr}
${t('station.settings.satellites.dopplerFactor')}: ${sat.dopplerFactor.toFixed(7)}
${t('station.settings.satellites.status')}: ${isVisible ? `${t('station.settings.satellites.visible')}` : `${t('station.settings.satellites.belowHorizon')}`}
${t('station.settings.satellites.mode')}:${sat.mode || 'N/A'}${sat.mode || 'N/A'}
${t('station.settings.satellites.downlink')}:${sat.downlink}
${t('station.settings.satellites.uplink')}:${sat.uplink}
${t('station.settings.satellites.tone')}:${sat.tone}
${t('station.settings.satellites.downlink')}:${sat.downlink}
${t('station.settings.satellites.uplink')}:${sat.uplink}
${t('station.settings.satellites.tone')}:${sat.tone}
- ${sat.notes ? `
${sat.notes}
` : ''} + ${sat.notes ? `
${sat.notes}
` : ''}
`; }) From 2c215e3ed7def579c67c5857e8c093b74e2e0cf2 Mon Sep 17 00:00:00 2001 From: Michael R Wheeley Date: Tue, 14 Apr 2026 13:40:21 -0700 Subject: [PATCH 13/14] limit station altitude [-500, 9000]m, defaults from || to ??, remove tle1, tle2 from positions --- src/components/SettingsPanel.jsx | 10 ++++++---- src/hooks/useSatellites.js | 2 -- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/SettingsPanel.jsx b/src/components/SettingsPanel.jsx index f9373433..14378656 100644 --- a/src/components/SettingsPanel.jsx +++ b/src/components/SettingsPanel.jsx @@ -179,10 +179,10 @@ export const SettingsPanel = ({ if (config) { setCallsign(config.callsign || ''); setheaderSize(config.headerSize || 1.0); - setLat(config.location?.lat || 0); - setLon(config.location?.lon || 0); - setStationAlt(config.location?.stationAlt || 100); - setMinElev(config.satellite?.minElev || 5.0); + setLat(config.location?.lat ?? 0); + setLon(config.location?.lon ?? 0); + setStationAlt(config.location?.stationAlt ?? 100); + setMinElev(config.satellite?.minElev ?? 5.0); setLayout(config.layout || 'modern'); setMouseZoom(config.mouseZoom || 50); setTimezone(config.timezone || ''); @@ -3385,6 +3385,8 @@ export const SettingsPanel = ({ setStationAlt(isNaN(e.target.valueAsNumber) ? 100 : e.target.valueAsNumber) diff --git a/src/hooks/useSatellites.js b/src/hooks/useSatellites.js index 20aa0c1d..6753632f 100644 --- a/src/hooks/useSatellites.js +++ b/src/hooks/useSatellites.js @@ -128,8 +128,6 @@ export const useSatellites = (observerLocation, satelliteConfig) => { positions.push({ name: tle.name || name, - tle1: line1, - tle2: line2, lat, lon, alt: round(alt, 1), From d71a5303efd69817f0400c390b6f38d4abdd37c5 Mon Sep 17 00:00:00 2001 From: Michael R Wheeley Date: Thu, 16 Apr 2026 09:14:26 -0700 Subject: [PATCH 14/14] fix bug where zero minimum elevation is reverting to 5 --- src/components/SettingsPanel.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/SettingsPanel.jsx b/src/components/SettingsPanel.jsx index 14378656..d086974e 100644 --- a/src/components/SettingsPanel.jsx +++ b/src/components/SettingsPanel.jsx @@ -424,7 +424,7 @@ export const SettingsPanel = ({ swapHeaderClocks, showMutualReception, location: { lat: parseFloat(lat) || 0, lon: parseFloat(lon) || 0, stationAlt: parseInt(stationAlt) || 100 }, - satellite: { minElev: parseFloat(minElev) || 5.0 }, + satellite: { minElev: isNaN(parseFloat(minElev)) ? 5.0 : parseFloat(minElev) }, theme, customTheme, layout,