mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 18:34:02 +00:00
Main moved the UI to Vue views and Pinia stores, so the Arabic changes to the old DOM controllers now live in their views: the rail legend range comes from formatScaleRange (keeping units a source supplies as given), the voice timeout options are worded by Intl unit formatting in VoiceControl, and the scene editor's JSON fields stay left to right in SceneDialog. Main's CCTV status line, launch panel and calibration values keep the Arabic isolates and Western-digit formatting. isolate() and keepCodesWithValues() read the locale through getLocale(), which follows the page's vue-i18n instance, and the Intl formatters take intlLocale(getLocale()). A language switch now applies in place, and applyDocumentLanguage sets <html dir> on every switch, so the page mirrors without a reload. The icon rails and their tips are placed with logical properties, so they stay on the outer side of the mirrored stacks; Cyber's new stack offsets, padding and edge lines are logical too, and rtl.css moves Cyber's right stack to its new rail clearance. Main removed the Context mini radio, so its right-to-left rules and test go. The Arabic catalog gains main's new strings and drops the ones main no longer uses; the other catalogs keep main's new keys and the branch's landing labels.
79 lines
2.6 KiB
JavaScript
79 lines
2.6 KiB
JavaScript
import { formatNumber, getLocale, isolate, msg, t } from '../i18n/index.js';
|
|
|
|
// Unit ids stay English in data, params and AI-tool readings; only the label
|
|
// shown on the page is translated. dBZ and °C read the same in every language.
|
|
const UNIT_LABELS = Object.freeze({
|
|
'km/h': msg('km/h'),
|
|
'm/s': msg('m/s'),
|
|
mph: msg('mph'),
|
|
hPa: msg('hPa'),
|
|
kt: msg('kt'),
|
|
kts: msg('kts'),
|
|
ft: msg('ft'),
|
|
km: msg('km'),
|
|
m: msg('m'),
|
|
h: msg('h'),
|
|
min: msg('min'),
|
|
s: msg('s'),
|
|
dB: msg('dB'),
|
|
});
|
|
|
|
/** The display label for a unit id; unknown units pass through unchanged. */
|
|
export function unitLabel(unit) {
|
|
return Object.hasOwn(UNIT_LABELS, unit) ? t(UNIT_LABELS[unit]) : unit || '';
|
|
}
|
|
|
|
/**
|
|
* What goes between a number and its unit label: a no-break space, except
|
|
* before a Japanese unit word, which follows the number directly (5分, 1時間).
|
|
*/
|
|
export function quantitySeparator(label) {
|
|
return getLocale() === 'ja' &&
|
|
/^[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}]/u.test(label)
|
|
? ''
|
|
: '\u00a0';
|
|
}
|
|
|
|
/**
|
|
* A number and its unit that never break apart: "22,0 км/ч". Readings carry
|
|
* no digit grouping ("1008 hPa"), as on weather charts.
|
|
*/
|
|
export function formatQuantity(value, unit, options) {
|
|
const label = unitLabel(unit);
|
|
const number = formatNumber(value, { useGrouping: false, ...options });
|
|
return label
|
|
? isolate(`${number}${quantitySeparator(label)}${label}`)
|
|
: number;
|
|
}
|
|
|
|
/**
|
|
* A legend stop such as "0.1", "-40" or "300+" in the active language.
|
|
* Anything that is not a plain number is shown as given. In right-to-left
|
|
* text the stop is isolated, so its sign stays where it is written ("300+",
|
|
* "-40") instead of moving to the other side of the number.
|
|
*/
|
|
export function formatScaleLabel(label) {
|
|
const match = /^(-?\d+(?:\.\d+)?)(\+?)$/.exec(String(label ?? ''));
|
|
if (!match) return String(label ?? '');
|
|
const decimals = match[1].split('.')[1]?.length || 0;
|
|
return isolate(
|
|
`${formatNumber(Number(match[1]), {
|
|
useGrouping: false,
|
|
minimumFractionDigits: decimals,
|
|
maximumFractionDigits: decimals,
|
|
})}${match[2]}`,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* A legend range with its unit: "960 — 1050+ hPa". The unit stays with the
|
|
* last number. In right-to-left text the unit is isolated as well, so a Latin
|
|
* unit keeps its own order ("°C", not "C°"). Units a source supplied as data
|
|
* (`verbatim`) are shown as given.
|
|
*/
|
|
export function formatScaleRange(low, high, units, verbatim = false) {
|
|
const unit = verbatim ? units || '' : unitLabel(units);
|
|
const range = `${formatScaleLabel(low)} — ${formatScaleLabel(high)}`;
|
|
return unit ? `${range}\u00a0${isolate(unit)}` : range;
|
|
}
|