Skip to content

Commit

Permalink
VPN-6622: Fix broken device language for Chinese (#9933) (#9968)
Browse files Browse the repository at this point in the history
* VPN-6622 fix for iOS

* make it generalizable to help with Android

* make it generalizable to help with Android

* better iOS explanation

* make linter happy

* update tests, improve logic for non-iOS
  • Loading branch information
mcleinman authored Oct 17, 2024
1 parent 9d847c6 commit c87152f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 9 deletions.
49 changes: 44 additions & 5 deletions src/localizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ QList<QPair<QString, QString>> Localizer::parseBCP47Languages(
continue;
}

// Chinese is often reported as `zh-Hant-HK`, and we want the middle
// section.
QString script = parts[1];
if (script == "Hans" || script == "Hant") {
codes.append(QPair<QString, QString>{parts[0], script});
continue;
}

QString country = parts.last();
if (country.length() == 2) {
codes.append(QPair<QString, QString>{parts[0], country});
Expand All @@ -96,11 +104,23 @@ QList<QPair<QString, QString>> Localizer::parseIOSLanguages(
QList<QPair<QString, QString>> codes;

for (const QString& language : languages) {
// By documentation, the language code should be in the format
// <language>-<script>_<country>. And we don't care about the script.
// The language code comes in the format <language>-<country> or
// <language>-<script>-<country>.
// For an iOS device set to these 6 languages: Chinese Traditional (Macao),
// Chinese Traditional, Chinese Simplified, English, Mexican Spanish,
// Spanish
// ...we get these language codes:
// [zh-Hant-MO,zh-Hant-US,zh-Hans-US,en-US,es-MX,es-US]
// iOS shows the 2 part versions for nearly all languages, and shows the
// 3 part version only when there is a script - like for Chinese variants.
// Thus, we can pull the second chunk of the locale string in all cases to
// get the translations flow required by our app. That second chunk gives
// the country for all languages except Chinese, where it gives the script -
// and in both these situations, this is what we want (script for Chinese,
// country for all others).
QString countryCode;

QStringList parts = language.split('_');
QStringList parts = language.split('-');
if (parts.length() > 1) {
countryCode = parts[1];
}
Expand All @@ -125,8 +145,27 @@ QString Localizer::systemLanguageCode() const {
#endif

for (const QPair<QString, QString>& language : uiLanguages) {
QString selectedLanguage =
findLanguageCode(language.first, language.second);
QString languagePart = language.first;
QString localePart = language.second;

// iOS reports Chinese as "zh-Hans" and "zh-Hant". Android reports
// them as "zh-CN" and "zh-Hans". However the app uses "zh-CN" and
// "zh-TW". We need to manually adjust these. More info:
// https://stackoverflow.com/questions/4892372/language-codes-for-simplified-chinese-and-traditional-chinese
// (For country-specific variants, it reports it as "zh-Hant-MO", etc. Since
// the app only looks at the strings before the 1st and 2nd dashes, we
// ignore the country - which is what we want to do, as we don't have
// translations for Chinese beyond simplified and traditional.)
if (languagePart == "zh") {
if (localePart == "Hans") {
localePart = "CN";
}
if (localePart == "Hant") {
localePart = "TW";
}
}

QString selectedLanguage = findLanguageCode(languagePart, localePart);
if (!selectedLanguage.isEmpty()) {
return selectedLanguage;
}
Expand Down
8 changes: 4 additions & 4 deletions tests/unit_tests/testlocalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,17 @@ void TestLocalizer::parseIOSLanguages_data() {
{
LanguageList a;
a.append(QPair<QString, QString>{"aa", "bb"});
QTest::addRow("language_country") << QStringList("aa_bb") << a;
QTest::addRow("language-country") << QStringList("aa-bb") << a;
}
{
LanguageList a;
a.append(QPair<QString, QString>{"aa", ""});
a.append(QPair<QString, QString>{"aa", "cc"});
QTest::addRow("language-script") << QStringList("aa-cc") << a;
}
{
LanguageList a;
a.append(QPair<QString, QString>{"aa", "bb"});
QTest::addRow("language-script_country") << QStringList("aa-cc_bb") << a;
a.append(QPair<QString, QString>{"aa", "cc"});
QTest::addRow("language-script-country") << QStringList("aa-cc-bb") << a;
}
}

Expand Down

0 comments on commit c87152f

Please sign in to comment.