jellyfin-tools/jellyfin-year-review/web/src/lib/i18n.js
jellyfin-year-review/web/src/lib/i18n.jsRaw
1import translations from './translations.json' with { type: 'json' };
2
3// Select one catalog for the entire build, including page language and formatting.
4if (!Object.hasOwn(translations.languages, translations.language)) {
5 throw new Error(`Unknown translation language: ${translations.language}`);
6}
7const catalog = translations.languages[translations.language];
8export const locale = catalog.locale;
9export const direction = catalog.direction;
10
11// Replace named placeholders once, keeping inserted names and titles as plain text.
12export function t(english, values = {}) {
13 const translated = Object.hasOwn(catalog.strings, english) ? catalog.strings[english] : english;
14 return translated.replace(/\{(\w+)\}/g, (placeholder, name) => Object.hasOwn(values, name) ? String(values[name]) : placeholder);
15}
16
17const countedMessages = [
18 '{count} records excluded because media metadata was deleted or unavailable.',
19 '{count} aggregate activity records; records may combine resumed viewing.'
20];
21
22// Review exports contain English messages; translate them without changing stored data.
23export function message(english) {
24 if (!english) return '';
25 for (const template of countedMessages) {
26 const suffix = template.slice('{count}'.length);
27 if (english.endsWith(suffix)) {
28 const count = english.slice(0, -suffix.length);
29 if (/^\d+$/.test(count)) return t(template, { count: new Intl.NumberFormat(locale).format(Number(count)) });
30 }
31 }
32 return t(english);
33}