diff options
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), ); |
