mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
Mark every UI string the unmarked-text check reported (534) plus text it cannot see (helpers, joined labels, runtime-built panels), and translate the result to Spanish and Russian: 1,679 messages each. - Kept on purpose, with the reason where the text lives: provider and product names, place and camera names, codes and units, dB values, the HUD terminal readouts, demo shot titles that saved projects look up by title, and text for AI tools and the voice model. - Modules shared with the server or AI tools stay free of the i18n import (local msg); the wind reading and voice session stay English and are translated where the page shows them. - npm test now runs the unmarked-text check. - Fixes on the way: a duplicated radio privacy paragraph, the contact panel toggle saying Expand while open, the CSS filter mistaking & for CSS. Co-Authored-By: Claude Opus 5.5 <[email protected]>
86 lines
2.4 KiB
JavaScript
86 lines
2.4 KiB
JavaScript
import { t } from '../i18n/index.js';
|
|
/** Count rendered globe frames while the optional readout is visible. */
|
|
export function createFrameRateMonitor({ viewer, documentRef = document }) {
|
|
const host = documentRef.getElementById('title-bar');
|
|
const frameEvent = viewer?.scene?.postRender;
|
|
if (!host || !frameEvent) return { destroy() {} };
|
|
|
|
const readout = documentRef.createElement('div');
|
|
readout.className = 'frame-rate-readout';
|
|
readout.hidden = true;
|
|
// i18n-ignore: FPS is a unit code, the same in every language
|
|
readout.textContent = 'FPS —';
|
|
readout.title = t('Rendered globe frames per second · toggle with `');
|
|
host.appendChild(readout);
|
|
let removeFrameListener = null;
|
|
let timer = null;
|
|
let frames = 0;
|
|
let startedAt = 0;
|
|
let destroyed = false;
|
|
|
|
function hide() {
|
|
readout.hidden = true;
|
|
removeFrameListener?.();
|
|
removeFrameListener = null;
|
|
clearInterval(timer);
|
|
timer = null;
|
|
}
|
|
|
|
function show() {
|
|
frames = 0;
|
|
startedAt = performance.now();
|
|
// i18n-ignore: FPS is a unit code, the same in every language
|
|
readout.textContent = 'FPS —';
|
|
readout.hidden = false;
|
|
removeFrameListener = frameEvent.addEventListener(() => {
|
|
frames++;
|
|
});
|
|
timer = setInterval(() => {
|
|
const now = performance.now();
|
|
const elapsed = now - startedAt;
|
|
readout.textContent =
|
|
// i18n-ignore: FPS is a unit code, the same in every language
|
|
documentRef.hidden || elapsed <= 0
|
|
? 'FPS —'
|
|
: `FPS ${Math.round((frames * 1000) / elapsed)}`;
|
|
frames = 0;
|
|
startedAt = now;
|
|
}, 1000);
|
|
}
|
|
|
|
function onKeyDown(event) {
|
|
if (event.key !== '`' && event.code !== 'Backquote') return;
|
|
if (
|
|
event.defaultPrevented ||
|
|
event.repeat ||
|
|
event.isComposing ||
|
|
event.ctrlKey ||
|
|
event.altKey ||
|
|
event.metaKey ||
|
|
event.shiftKey
|
|
)
|
|
return;
|
|
if (
|
|
event.target?.isContentEditable ||
|
|
event.target?.closest?.(
|
|
'input, textarea, select, [contenteditable]:not([contenteditable="false"])',
|
|
)
|
|
)
|
|
return;
|
|
event.preventDefault();
|
|
if (readout.hidden) show();
|
|
else hide();
|
|
}
|
|
|
|
documentRef.addEventListener('keydown', onKeyDown);
|
|
return {
|
|
destroy() {
|
|
if (destroyed) return;
|
|
destroyed = true;
|
|
hide();
|
|
documentRef.removeEventListener('keydown', onKeyDown);
|
|
readout.remove();
|
|
},
|
|
};
|
|
}
|