Skip to content

Commit c87152f

Browse files
authored
VPN-6622: Fix broken device language for Chinese (#9933) (#9968)
* 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
1 parent 9d847c6 commit c87152f

File tree

2 files changed

+48
-9
lines changed

2 files changed

+48
-9
lines changed

src/localizer.cpp

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ QList<QPair<QString, QString>> Localizer::parseBCP47Languages(
7777
continue;
7878
}
7979

80+
// Chinese is often reported as `zh-Hant-HK`, and we want the middle
81+
// section.
82+
QString script = parts[1];
83+
if (script == "Hans" || script == "Hant") {
84+
codes.append(QPair<QString, QString>{parts[0], script});
85+
continue;
86+
}
87+
8088
QString country = parts.last();
8189
if (country.length() == 2) {
8290
codes.append(QPair<QString, QString>{parts[0], country});
@@ -96,11 +104,23 @@ QList<QPair<QString, QString>> Localizer::parseIOSLanguages(
96104
QList<QPair<QString, QString>> codes;
97105

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

103-
QStringList parts = language.split('_');
123+
QStringList parts = language.split('-');
104124
if (parts.length() > 1) {
105125
countryCode = parts[1];
106126
}
@@ -125,8 +145,27 @@ QString Localizer::systemLanguageCode() const {
125145
#endif
126146

127147
for (const QPair<QString, QString>& language : uiLanguages) {
128-
QString selectedLanguage =
129-
findLanguageCode(language.first, language.second);
148+
QString languagePart = language.first;
149+
QString localePart = language.second;
150+
151+
// iOS reports Chinese as "zh-Hans" and "zh-Hant". Android reports
152+
// them as "zh-CN" and "zh-Hans". However the app uses "zh-CN" and
153+
// "zh-TW". We need to manually adjust these. More info:
154+
// https://stackoverflow.com/questions/4892372/language-codes-for-simplified-chinese-and-traditional-chinese
155+
// (For country-specific variants, it reports it as "zh-Hant-MO", etc. Since
156+
// the app only looks at the strings before the 1st and 2nd dashes, we
157+
// ignore the country - which is what we want to do, as we don't have
158+
// translations for Chinese beyond simplified and traditional.)
159+
if (languagePart == "zh") {
160+
if (localePart == "Hans") {
161+
localePart = "CN";
162+
}
163+
if (localePart == "Hant") {
164+
localePart = "TW";
165+
}
166+
}
167+
168+
QString selectedLanguage = findLanguageCode(languagePart, localePart);
130169
if (!selectedLanguage.isEmpty()) {
131170
return selectedLanguage;
132171
}

tests/unit_tests/testlocalizer.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,17 +158,17 @@ void TestLocalizer::parseIOSLanguages_data() {
158158
{
159159
LanguageList a;
160160
a.append(QPair<QString, QString>{"aa", "bb"});
161-
QTest::addRow("language_country") << QStringList("aa_bb") << a;
161+
QTest::addRow("language-country") << QStringList("aa-bb") << a;
162162
}
163163
{
164164
LanguageList a;
165-
a.append(QPair<QString, QString>{"aa", ""});
165+
a.append(QPair<QString, QString>{"aa", "cc"});
166166
QTest::addRow("language-script") << QStringList("aa-cc") << a;
167167
}
168168
{
169169
LanguageList a;
170-
a.append(QPair<QString, QString>{"aa", "bb"});
171-
QTest::addRow("language-script_country") << QStringList("aa-cc_bb") << a;
170+
a.append(QPair<QString, QString>{"aa", "cc"});
171+
QTest::addRow("language-script-country") << QStringList("aa-cc-bb") << a;
172172
}
173173
}
174174

0 commit comments

Comments
 (0)