mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 03:14:00 +00:00
fix(voice): Navara refusals reach speech, analyst queries and stop_tracking
Review of 10a (low): - The spoken answer to set_layer_visibility on a layer this engine lacks is the refusal's own sentence (why, and the switch to ?engine=cesium), not only "Couldn't turn on". - analyst_query naming layers the catalog left out (no viewer) refuses with UNAVAILABLE_ON_ENGINE and the layer ids instead of answering zero. - stop_tracking skips layers the engine does not have, so with nothing tracked it is a no-op success on Navara (it reported the absent military and satellites layers as failures). Tests for each (the old code fails the last two); Cesium unchanged.
This commit is contained in:
1 parent
443c581280
commit
1dd3220812
3 files changed
+86
-1
No files matched your search
+28
-1
@@ -332,7 +332,9 @@ function unavailableOnEngine(
|
|||||||
engine: engine?.kind ?? null,
|
engine: engine?.kind ?? null,
|
||||||
feature: what,
|
feature: what,
|
||||||
suggestion: SWITCH_ENGINE_HINT,
|
suggestion: SWITCH_ENGINE_HINT,
|
||||||
error: `${what} is not available on ${engineName(engine)} yet. Switch to the Cesium engine (${SWITCH_ENGINE_HINT}) to use it.`,
|
error: /\blayers$/.test(what)
|
||||||
|
? `${what} are not available on ${engineName(engine)} yet. Switch to the Cesium engine (${SWITCH_ENGINE_HINT}) to use them.`
|
||||||
|
: `${what} is not available on ${engineName(engine)} yet. Switch to the Cesium engine (${SWITCH_ENGINE_HINT}) to use it.`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1110,6 +1112,29 @@ export function createGevActionRunner({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (name === 'analyst_query') {
|
if (name === 'analyst_query') {
|
||||||
|
// Layers this engine's catalog left out cannot be asked: say so rather
|
||||||
|
// than answer zero.
|
||||||
|
const missing = !viewer
|
||||||
|
? (Array.isArray(args.layers) ? args.layers : [])
|
||||||
|
.map(normalizeLayerId)
|
||||||
|
.filter(
|
||||||
|
(layerId) =>
|
||||||
|
layerId &&
|
||||||
|
voiceLayer(layerId) &&
|
||||||
|
!dataManager.layers.has(layerId),
|
||||||
|
)
|
||||||
|
: [];
|
||||||
|
if (missing.length)
|
||||||
|
return {
|
||||||
|
...unavailableOnEngine(
|
||||||
|
'analyst_query',
|
||||||
|
engine,
|
||||||
|
missing.length === 1
|
||||||
|
? `The ${missing[0]} layer`
|
||||||
|
: `The ${missing.join(', ')} layers`,
|
||||||
|
),
|
||||||
|
layerIds: missing,
|
||||||
|
};
|
||||||
return runAnalystQuery(
|
return runAnalystQuery(
|
||||||
ensureAnalystEngine(),
|
ensureAnalystEngine(),
|
||||||
dataManager,
|
dataManager,
|
||||||
@@ -2484,6 +2509,8 @@ function stopAllTracking(engine, dataManager) {
|
|||||||
['military', 'selectedMilitaryTrackingId'],
|
['military', 'selectedMilitaryTrackingId'],
|
||||||
['satellites', 'selectedSatTrackingId'],
|
['satellites', 'selectedSatTrackingId'],
|
||||||
]) {
|
]) {
|
||||||
|
// A layer this engine does not have tracks nothing to clear.
|
||||||
|
if (dataManager.layers && !dataManager.layers.has(layerId)) continue;
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
dataManager.setLayerParams(
|
dataManager.setLayerParams(
|
||||||
|
|||||||
@@ -504,3 +504,54 @@ test('without a viewer a layer the engine lacks refuses instead of throwing', as
|
|||||||
'a name no engine knows is still an unknown layer',
|
'a name no engine knows is still an unknown layer',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('without a viewer analyst_query on a layer the engine lacks refuses', async () => {
|
||||||
|
const engine = engineOverAustin({ kind: 'navara' });
|
||||||
|
const runner = runnerOn(engine, {
|
||||||
|
dataManager: dataManagerWith({ flights: {} }),
|
||||||
|
});
|
||||||
|
const one = await runner('analyst_query', { layers: ['cctv'] });
|
||||||
|
assert.equal(one.ok, false);
|
||||||
|
assert.equal(one.code, UNAVAILABLE_ON_ENGINE);
|
||||||
|
assert.deepEqual(one.layerIds, ['cctv']);
|
||||||
|
assert.match(
|
||||||
|
one.error,
|
||||||
|
/^The cctv layer is not available on the Navara engine yet/,
|
||||||
|
);
|
||||||
|
const two = await runner('analyst_query', { layers: ['cctv', 'vessels'] });
|
||||||
|
assert.match(
|
||||||
|
two.error,
|
||||||
|
/^The cctv, ais-live-vessels layers are not available on the Navara engine yet\. Switch to the Cesium engine \(\?engine=cesium\) to use them\.$/,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('stop_tracking with nothing tracked is a no-op success, also without the layers', async () => {
|
||||||
|
const engine = engineOverAustin({ kind: 'navara' });
|
||||||
|
const dataManager = dataManagerWith({
|
||||||
|
flights: { getTrackedInfo: () => null },
|
||||||
|
});
|
||||||
|
// As the manager answers: a layer it does not hold takes no params.
|
||||||
|
dataManager.setLayerParams = (id) => dataManager.layers.has(id);
|
||||||
|
const runner = runnerOn(engine, { dataManager });
|
||||||
|
const result = await runner('stop_tracking', {});
|
||||||
|
assert.equal(result.ok, true);
|
||||||
|
assert.deepEqual(result.released, []);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('the spoken refusal of an unavailable layer carries its reason', async () => {
|
||||||
|
const { SPEECH_BUILDERS } = await import('./speech.js');
|
||||||
|
const engine = engineOverAustin({ kind: 'navara' });
|
||||||
|
const runner = runnerOn(engine, {
|
||||||
|
dataManager: dataManagerWith({ flights: {} }),
|
||||||
|
});
|
||||||
|
const result = await runner('set_layer_visibility', {
|
||||||
|
layerId: 'cctv',
|
||||||
|
enabled: true,
|
||||||
|
});
|
||||||
|
const speech = SPEECH_BUILDERS.set_layer_visibility(result, {
|
||||||
|
layerId: 'cctv',
|
||||||
|
enabled: true,
|
||||||
|
});
|
||||||
|
assert.equal(speech.say, result.error);
|
||||||
|
assert.match(speech.say, /Switch to the Cesium engine/);
|
||||||
|
});
|
||||||
@@ -103,6 +103,13 @@ function setLayerVisibility(result, args = {}) {
|
|||||||
if (result?.cancelled) return null;
|
if (result?.cancelled) return null;
|
||||||
if (!result?.ok) {
|
if (!result?.ok) {
|
||||||
const wanted = args.enabled === false ? 'off' : 'on';
|
const wanted = args.enabled === false ? 'off' : 'on';
|
||||||
|
// An engine without the layer says why and what to do (the refusal's
|
||||||
|
// own sentence), not only that it failed.
|
||||||
|
if (result?.code === 'UNAVAILABLE_ON_ENGINE' && result.error)
|
||||||
|
return {
|
||||||
|
say: result.error,
|
||||||
|
display: { title: label, lines: [result.error] },
|
||||||
|
};
|
||||||
return {
|
return {
|
||||||
say: `Couldn't turn ${wanted} ${label}.`,
|
say: `Couldn't turn ${wanted} ${label}.`,
|
||||||
display: { title: label, lines: [result?.error].filter(Boolean) },
|
display: { title: label, lines: [result?.error].filter(Boolean) },
|
||||||
|
|||||||
Reference in new issue
Block a user