diff options
| author | Oskar <oskar@mullvad.net> | 2025-09-26 11:15:50 +0200 |
|---|---|---|
| committer | Oskar <oskar@mullvad.net> | 2025-10-31 09:46:49 +0100 |
| commit | 5bd367b10359641d7a7fb7f5d974c26316d2bbf7 (patch) | |
| tree | 677d702602af6981b5905b765ed6c4ebce30af65 | |
| parent | 5cc42981d59058b766b0c110ea86464b9faf32de (diff) | |
| download | mullvadvpn-5bd367b10359641d7a7fb7f5d974c26316d2bbf7.tar.xz mullvadvpn-5bd367b10359641d7a7fb7f5d974c26316d2bbf7.zip | |
Add robber language
3 files changed, 72 insertions, 2 deletions
diff --git a/desktop/packages/mullvad-vpn/src/main/load-translations.ts b/desktop/packages/mullvad-vpn/src/main/load-translations.ts index c16f8695de..670e9a2a5b 100644 --- a/desktop/packages/mullvad-vpn/src/main/load-translations.ts +++ b/desktop/packages/mullvad-vpn/src/main/load-translations.ts @@ -47,7 +47,8 @@ function parseTranslation( domain: string, catalogue: Gettext, ): GetTextTranslations | undefined { - const filename = path.join(LOCALES_DIR, locale, `${domain}.po`); + const aliasedLocale = getAliasedLocale(locale); + const filename = path.join(LOCALES_DIR, aliasedLocale, `${domain}.po`); let contents: string; try { @@ -69,7 +70,68 @@ function parseTranslation( return undefined; } - catalogue.addTranslations(locale, domain, translations); + if (locale === 'sv-rö') { + robberifyTranslations(translations); + } + + catalogue.addTranslations(aliasedLocale, domain, translations); return translations; } + +function getAliasedLocale(locale: string): string { + return locale === 'sv-rö' ? 'sv' : locale; +} + +function robberifyTranslations(translations: GetTextTranslations) { + for (const contextKey in translations.translations) { + const context = translations.translations[contextKey]; + + for (const messageKey in context) { + const message = context[messageKey]; + + if (!message.msgstr[0].startsWith('Content-Type:')) { + message.msgstr = message.msgstr.map((msgstr) => robberifyString(msgstr)); + } + } + } +} + +const CONSONANTS = 'bcdfghjklmnpqrstvxzBCDFGHJKLMNPQRSTVXZ'; +const PLACEHOLDER_TYPES = ['s', 'd']; + +function robberifyString(value: string): string { + let robberValue = ''; + + const chars = value.split(''); + let skipDueTo: string | null = null; + for (let i = 0; i < chars.length; i++) { + const char = chars[i]; + const nextChar = i < chars.length - 1 ? chars[i + 1] : ''; + + if (char === '<') { + skipDueTo = char; + robberValue += char; + } else if (skipDueTo === '<' && char === '>') { + skipDueTo = null; + robberValue += char; + } else if (char === '%' && PLACEHOLDER_TYPES.includes(nextChar)) { + robberValue += `${char}${nextChar}`; + i++; + } else if (char === '%' && nextChar === '(') { + skipDueTo = char; + robberValue += `${char}${nextChar}`; + i++; + } else if (skipDueTo === '%' && char === ')' && PLACEHOLDER_TYPES.includes(nextChar)) { + skipDueTo = null; + robberValue += `${char}${nextChar}`; + i++; + } else if (skipDueTo === null && CONSONANTS.includes(char)) { + robberValue += `${char}o${char.toLowerCase()}`; + } else { + robberValue += char; + } + } + + return robberValue; +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/app.tsx b/desktop/packages/mullvad-vpn/src/renderer/app.tsx index 74b4fd1c6c..45ddfb5354 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/app.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/app.tsx @@ -98,6 +98,10 @@ const SUPPORTED_LOCALE_LIST = [ { name: '繁體中文', code: 'zh-TW' }, ]; +if (window.env.development) { + SUPPORTED_LOCALE_LIST.push({ name: 'Rövarspråket', code: 'sv-rö' }); +} + export default class AppRenderer { private history: History; private reduxStore = configureStore(); diff --git a/desktop/packages/mullvad-vpn/src/shared/account-expiry.ts b/desktop/packages/mullvad-vpn/src/shared/account-expiry.ts index 1b40848220..4e5cac3065 100644 --- a/desktop/packages/mullvad-vpn/src/shared/account-expiry.ts +++ b/desktop/packages/mullvad-vpn/src/shared/account-expiry.ts @@ -18,6 +18,10 @@ export function closeToExpiry(expiry: DateType, days = 3): boolean { } export function formatDate(date: DateType, locale: string): string { + if (window.env.development && locale === 'sv-rö') { + locale = 'sv'; + } + return new Intl.DateTimeFormat(locale, { dateStyle: 'medium', timeStyle: 'short' }).format( new Date(date), ); |
