diff --git a/src/ui/cameraOrientationControls.test.mjs b/src/ui/cameraOrientationControls.test.mjs index 43ce28e91..1b3d3445d 100644 --- a/src/ui/cameraOrientationControls.test.mjs +++ b/src/ui/cameraOrientationControls.test.mjs @@ -811,3 +811,36 @@ test("north-up and tilt inside an engine's own follow keep following (Navara)", handle.stop(); engine.destroy(); }); + +test('a navigation releases the flights follow when military awareness has no controls (Navara)', () => { + const stopped = []; + const navigation = new NavigationController({ + viewer: null, + engine: createFakeEngine(), + tracking: { + flightsLayer: { + stopTracking: ({ origin }) => stopped.push(`flights:${origin}`), + }, + militaryFlightsLayer: { + stopTracking: ({ origin }) => stopped.push(`military:${origin}`), + }, + satellitesLayer: {}, + aisLiveVesselsLayer: { clearSelection: () => stopped.push('vessels') }, + // A layer this engine leaves out: its module, without the controls. + militaryAwarenessLayer: {}, + rocketLaunchesLayer: {}, + }, + isCockpitActive: () => false, + cancelOrientation() {}, + clearLocation() {}, + cancelShareSelection() {}, + interruptCameraMotion() {}, + stopOrbit() {}, + showToast() {}, + }); + assert.equal( + navigation._releaseFollowCamera({ preserveVesselSelection: false }), + false, + ); + assert.deepEqual(stopped, ['flights:tool', 'military:tool', 'vessels']); +}); diff --git a/src/ui/locationNavigation.js b/src/ui/locationNavigation.js index 342a57b20..ca521b71c 100644 --- a/src/ui/locationNavigation.js +++ b/src/ui/locationNavigation.js @@ -327,6 +327,10 @@ export class LocationNavigation { this._stopOrbit(); this.cockpitView?.exit({ restoreTracking: false }); try { + // A layer an engine leaves out (military awareness on Navara) has no + // controls: release the trackers it would release, below. + if (typeof militaryAwarenessLayer?.releaseCameraOwnership !== 'function') + throw new Error('no military awareness controls'); militaryAwarenessLayer.releaseCameraOwnership?.({ origin: 'tool' }); } catch { // Keep reset available if Context has not initialized completely. diff --git a/src/ui/navigationController.js b/src/ui/navigationController.js index 44c866840..8c164bc7f 100644 --- a/src/ui/navigationController.js +++ b/src/ui/navigationController.js @@ -145,6 +145,10 @@ export class NavigationController { } = this.tracking; let contactSelected = false; try { + // A layer an engine leaves out (military awareness on Navara) has no + // controls: release the trackers it would release, below. + if (typeof militaryAwarenessLayer?.releaseCameraOwnership !== 'function') + throw new Error('no military awareness controls'); contactSelected = Boolean( militaryAwarenessLayer.releaseCameraOwnership?.({ preserveVesselSelection,