mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
Fixes the 51 P0–P2 findings from the full review of the i18n branch and the issues found while checking every new string on screen in ru and es. - Translate errors and statuses that still reached ru/es in English: feed and tile errors, provider statuses, the ALPR chip, the traffic mode chip, voice plan step labels, fire feed values, receiver bands, scene save reasons and the Cesium attribution link. - Show preset city names in the UI language (src/ui/placeNames.js); data and everything sent to the model stay English. - Share layer names between the layer panel, HUD and voice card (src/ui/layerNames.js). - Keep long ru/es strings whole: voice card error lines, analyst titles, the voice tier status, the Nepal evidence button, the ALPR retry chip. English layout is unchanged. - Ask before a language switch drops unsaved work. - Catalog fixes: glossary terms (пуск, пресет), gender agreement and consistent "peticiones" in es, fewer calques in both languages. - Fix English text that was itself wrong (e.g. "Exit cockpit to fly to a weather", raw tool ids in voice plan steps). Catalogs: es/ru 2535 messages each, complete. Co-Authored-By: Claude Opus 5.5 <[email protected]>
85 lines
3.0 KiB
JavaScript
85 lines
3.0 KiB
JavaScript
/**
|
|
* Adds the keyboard semantics omitted by Cesium's href-less attribution links.
|
|
* Cesium retains ownership of showing and hiding its required credit lightbox.
|
|
*/
|
|
import { getLocale, t } from './i18n/index.js';
|
|
|
|
export function configureCreditKeyboardAccess(root = document) {
|
|
const expand = root?.querySelector?.(
|
|
'#cesium-credits .cesium-credit-expand-link',
|
|
);
|
|
const lightbox = root?.querySelector?.('.cesium-credit-lightbox');
|
|
const close = lightbox?.querySelector?.('.cesium-credit-lightbox-close');
|
|
if (!expand || !lightbox || !close) return false;
|
|
const overlay = lightbox.parentElement;
|
|
|
|
// Cesium writes these two texts in English once, when it builds the credit
|
|
// display, and never rewrites them; English keeps Cesium's own text.
|
|
if (getLocale() !== 'en') {
|
|
expand.textContent = t('Data attribution');
|
|
const title = lightbox.querySelector?.('.cesium-credit-lightbox-title');
|
|
if (title) title.textContent = t('Data provided by:');
|
|
}
|
|
|
|
if (!lightbox.id) lightbox.id = 'cesium-credit-lightbox';
|
|
expand.setAttribute('role', 'button');
|
|
expand.setAttribute('tabindex', '0');
|
|
expand.setAttribute('aria-haspopup', 'dialog');
|
|
expand.setAttribute('aria-controls', lightbox.id);
|
|
expand.setAttribute('aria-expanded', 'false');
|
|
close.setAttribute('role', 'button');
|
|
close.setAttribute('tabindex', '0');
|
|
close.setAttribute('aria-label', t('Close data attribution'));
|
|
|
|
if (expand.dataset.gevKeyboardReady === 'true') return true;
|
|
expand.dataset.gevKeyboardReady = 'true';
|
|
|
|
const installKeyboardActivation = (control) => {
|
|
let spacePressed = false;
|
|
control.addEventListener('keydown', (event) => {
|
|
if (event.key === 'Enter') {
|
|
event.preventDefault();
|
|
if (!event.repeat) control.click();
|
|
return;
|
|
}
|
|
if (event.key !== ' ') return;
|
|
event.preventDefault();
|
|
if (!event.repeat) spacePressed = true;
|
|
});
|
|
control.addEventListener('keyup', (event) => {
|
|
if (event.key !== ' ') return;
|
|
event.preventDefault();
|
|
if (!spacePressed) return;
|
|
spacePressed = false;
|
|
control.click();
|
|
});
|
|
// A long Space hold may hand control to push-to-talk and move focus away.
|
|
// Cancelling the armed release prevents that eventual keyup from also
|
|
// activating the attribution control.
|
|
control.addEventListener('blur', () => {
|
|
spacePressed = false;
|
|
});
|
|
};
|
|
const closeAndRestoreFocus = () => {
|
|
expand.setAttribute('aria-expanded', 'false');
|
|
expand.focus();
|
|
};
|
|
installKeyboardActivation(expand);
|
|
installKeyboardActivation(close);
|
|
lightbox.addEventListener('keydown', (event) => {
|
|
if (event.key !== 'Escape' || event.defaultPrevented) return;
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
close.click();
|
|
});
|
|
expand.addEventListener('click', () => {
|
|
expand.setAttribute('aria-expanded', 'true');
|
|
close.focus();
|
|
});
|
|
close.addEventListener('click', closeAndRestoreFocus);
|
|
overlay?.addEventListener?.('click', (event) => {
|
|
if (!lightbox.contains(event.target)) closeAndRestoreFocus();
|
|
});
|
|
return true;
|
|
}
|