diff --git a/frontend/src/components/EarthTwin.tsx b/frontend/src/components/EarthTwin.tsx index 780975d..181ed95 100644 --- a/frontend/src/components/EarthTwin.tsx +++ b/frontend/src/components/EarthTwin.tsx @@ -16,6 +16,7 @@ import { import { useSpeechRecognition } from '../hooks/useSpeechRecognition'; import { executeVoiceCommand } from '../lib/voiceCommands'; +import { SpotlightManager } from './SatelliteSpotlight/SpotlightManager'; interface CatalogObject { id: number; @@ -137,18 +138,22 @@ const LegendCardSkeleton = () => (
); -export const EarthTwin: React.FC = () => { - const navigate = useNavigate(); export interface EarthTwinHandle { /** Flies the camera to the given NORAD catalog number and opens its info panel. */ flyToSatellite: (catalogNumber: string) => void; } export const EarthTwin = forwardRef((_props, ref) => { + const navigate = useNavigate(); const containerRef = useRef(null); const viewerRef = useRef(null); const entitiesRef = useRef>(new Map()); + const catalogMapRef = useRef>(new Map()); + const collisionSetRef = useRef>(new Set()); const tooltipRef = useRef(null); + const [viewerInstance, setViewerInstance] = useState(null); + const [containerEl, setContainerEl] = useState(null); + const [datasetVersion, setDatasetVersion] = useState(0); const { activeSector, setSelectedSatelliteId } = useUIStore(); const [useFallback, setUseFallback] = useState(true); // Set by flyToSatellite(), consumed by SpotlightManager to lock its @@ -251,6 +256,7 @@ export const EarthTwin = forwardRef((_props, ref) => { let payloads = 0, debris = 0, rocketBodies = 0; const entityMap = new Map(); + const catalogMap = new Map(); if (!viewer || viewer.isDestroyed()) return; @@ -301,6 +307,7 @@ export const EarthTwin = forwardRef((_props, ref) => { }); entityMap.set(obj.catalog_number, entity); + catalogMap.set(obj.catalog_number, obj); }); @@ -327,6 +334,9 @@ export const EarthTwin = forwardRef((_props, ref) => { }); entitiesRef.current = entityMap; + catalogMapRef.current = catalogMap; + collisionSetRef.current = collisionCatNums; + setDatasetVersion(v => v + 1); setObjectCounts({ payloads, debris, @@ -573,6 +583,10 @@ export const EarthTwin = forwardRef((_props, ref) => { viewerRef.current = viewer; // eslint-disable-next-line react-hooks/set-state-in-effect setUseFallback(false); + // eslint-disable-next-line react-hooks/set-state-in-effect + setViewerInstance(viewer); + // eslint-disable-next-line react-hooks/set-state-in-effect + setContainerEl(containerRef.current); viewer.scene.globe.enableLighting = true; // Enable real-time day/night lighting @@ -687,6 +701,8 @@ export const EarthTwin = forwardRef((_props, ref) => { v.destroy(); } viewerRef.current = null; + setViewerInstance(null); + setContainerEl(null); }; } catch (e) {