feat(Language): add locale formatting option and update translations

This commit is contained in:
alexsparkes
2026-01-24 21:54:14 +00:00
parent 6f1b81d503
commit 012d7bf5a8
39 changed files with 125 additions and 37 deletions

View File

@@ -4,7 +4,7 @@ import { useT, useTranslation } from 'contexts/TranslationContext';
import { MdOutlineOpenInNew, MdSearch, MdComputer } from 'react-icons/md';
import { TextField, InputAdornment } from '@mui/material';
import { Radio } from 'components/Form/Settings';
import { Radio, Checkbox } from 'components/Form/Settings';
import languages from '@/i18n/languages.json';
@@ -100,6 +100,13 @@ const LanguageOptions = () => {
</a>
</div>
</div>
<div style={{ marginBottom: '16px' }}>
<Checkbox
name="localeFormatting"
text={t('modals.main.settings.sections.language.locale_formatting')}
category="other"
/>
</div>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 }}>
<TextField
placeholder={t('modals.main.settings.sections.language.search')}

View File

@@ -16,6 +16,7 @@ import { Header, CustomActions } from 'components/Layout/Settings';
import { ClearModal } from './ClearModal';
import { saveFile } from 'utils/saveFile';
import { formatNumber } from 'utils/formatNumber';
import variables from 'config/variables';
import {
getLocalisedAchievementData,
@@ -82,7 +83,7 @@ const Stats = () => {
const StatsElement = ({ title, value }) => (
<div>
<span className="subtitle">{title}</span>
<span>{value}</span>
<span>{formatNumber(value)}</span>
</div>
);

View File

@@ -1,6 +1,7 @@
import { useState, useEffect, useRef } from 'react';
import { convertTimezone } from 'utils/date';
import { formatPercentage } from 'utils/formatNumber';
import { AnalogClock } from './components/AnalogClock';
import { VerticalClock } from './components/VerticalClock';
import EventBus from 'utils/eventbus';
@@ -33,7 +34,7 @@ const Clock = () => {
switch (localStorage.getItem('timeType')) {
case 'percentageComplete':
setTime((now.getHours() / 24).toFixed(2).replace('0.', '') + '%');
setTime(formatPercentage(now.getHours() / 24));
setAmpm('');
break;
case 'analogue':

View File

@@ -479,7 +479,8 @@
"quote": "لغة الاقتباس",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "سجل التغييرات",

View File

@@ -487,7 +487,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -479,7 +479,8 @@
"quote": "Sitat dili",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Dəyişikliklər Siyahısı",

View File

@@ -479,7 +479,8 @@
"quote": "Sitat dili",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Dəyişikliklər Siyahısı",

View File

@@ -479,7 +479,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -479,7 +479,8 @@
"quote": "Zitat-Sprache",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Änderungen",

View File

@@ -487,7 +487,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -479,7 +479,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -487,7 +487,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -479,7 +479,8 @@
"quote": "Idioma de las citas",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Registro de cambios",

View File

@@ -479,7 +479,8 @@
"quote": "Idioma de las citaciones",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Registro de cambios",

View File

@@ -479,7 +479,8 @@
"quote": "Tsitaadi keel",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Muudatuste logi",

View File

@@ -487,7 +487,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -479,7 +479,8 @@
"quote": "Langue des citations",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Journal des modifications",

View File

@@ -487,7 +487,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -479,7 +479,8 @@
"quote": "Bahasa untuk kutipan",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Changelog",

View File

@@ -487,7 +487,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -479,7 +479,8 @@
"quote": "Citatų kalba",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Pakeitimų žurnalas",

View File

@@ -479,7 +479,8 @@
"quote": "Citātu valoda",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Izmaiņu žurnāls",

View File

@@ -479,7 +479,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -479,7 +479,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -487,7 +487,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -479,7 +479,8 @@
"quote": "Idioma das citações",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Registo de alterações",

View File

@@ -479,7 +479,8 @@
"quote": "Idioma das citações",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Registo de alterações",

View File

@@ -479,7 +479,8 @@
"quote": "Язык цитат",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Журнал изменений",

View File

@@ -479,7 +479,8 @@
"quote": "Jezik citata",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Dnevnik sprememb",

View File

@@ -487,7 +487,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -479,7 +479,8 @@
"quote": "மேற்கோள் மொழி",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "பதிவை மாற்றவும்",

View File

@@ -479,7 +479,8 @@
"quote": "Alıntı dili",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Değişiklik Günlüğü",

View File

@@ -479,7 +479,8 @@
"quote": "Мова цитат",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Журнал змін",

View File

@@ -487,7 +487,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -479,7 +479,8 @@
"quote": "名言语言",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "更新日志",

View File

@@ -487,7 +487,8 @@
"quote": "Quote language",
"search": "Search languages...",
"current": "Current",
"use_system": "Use system language"
"use_system": "Use system language",
"locale_formatting": "Format numbers for your language"
},
"changelog": {
"title": "Change Log",

View File

@@ -41,7 +41,7 @@ import zh_Hant from 'translations/zh_Hant.json';
* @returns The i18n object.
*/
export function initTranslations(locale) {
const i18n = new I18n(locale, {
const i18n = new I18n('en_GB', {
ar,
arz,
az,

View File

@@ -235,6 +235,10 @@
"name": "statsData",
"value": "{}"
},
{
"name": "localeFormatting",
"value": false
},
{
"name": "offlineMode",
"value": false

42
src/utils/formatNumber.js Normal file
View File

@@ -0,0 +1,42 @@
/**
* Convert language code from Mue format (en_US) to locale format (en-US)
*/
export function getLocaleCode() {
return localStorage.getItem('language')?.replace(/_/g, '-') || 'en-GB';
}
/**
* Format number with locale awareness (if enabled)
* @param {number} value - The number to format
* @param {Intl.NumberFormatOptions} options - Optional Intl.NumberFormat options
* @returns {string} Formatted number string
*/
export function formatNumber(value, options = {}) {
if (localStorage.getItem('localeFormatting') !== 'true') {
return String(value);
}
try {
return new Intl.NumberFormat(getLocaleCode(), options).format(value);
} catch {
return String(value);
}
}
/**
* Format percentage with locale awareness (if enabled)
* @param {number} value - The decimal value (e.g., 0.45 for 45%)
* @returns {string} Formatted percentage string
*/
export function formatPercentage(value) {
if (localStorage.getItem('localeFormatting') !== 'true') {
return Math.round(value * 100) + '%';
}
try {
return new Intl.NumberFormat(getLocaleCode(), {
style: 'percent',
maximumFractionDigits: 0,
}).format(value);
} catch {
return Math.round(value * 100) + '%';
}
}