|
18 | 18 | import android.telephony.TelephonyManager;
|
19 | 19 | import android.text.TextUtils;
|
20 | 20 | import android.text.format.DateFormat;
|
| 21 | +import android.util.Log; |
21 | 22 | import android.util.Xml;
|
22 | 23 |
|
23 | 24 | import androidx.annotation.StringRes;
|
|
39 | 40 | import java.util.Currency;
|
40 | 41 | import java.util.Date;
|
41 | 42 | import java.util.HashMap;
|
| 43 | +import java.util.HashSet; |
42 | 44 | import java.util.Locale;
|
| 45 | +import java.util.Map; |
43 | 46 | import java.util.TimeZone;
|
44 | 47 |
|
45 | 48 | public class LocaleController {
|
@@ -487,17 +490,65 @@ public void reloadCurrentRemoteLocale(int currentAccount, String langCode, boole
|
487 | 490 | }
|
488 | 491 | }
|
489 | 492 |
|
| 493 | + private boolean checkingUpdateForCurrentRemoteLocale; |
| 494 | + |
490 | 495 | public void checkUpdateForCurrentRemoteLocale(int currentAccount, int version, int baseVersion) {
|
491 | 496 | if (currentLocaleInfo == null || !currentLocaleInfo.isRemote() && !currentLocaleInfo.isUnofficial()) {
|
492 | 497 | return;
|
493 | 498 | }
|
494 | 499 | if (currentLocaleInfo.hasBaseLang()) {
|
495 | 500 | if (currentLocaleInfo.baseVersion < baseVersion) {
|
496 |
| - applyRemoteLanguage(currentLocaleInfo, currentLocaleInfo.baseLangCode, false, currentAccount, null); |
| 501 | + checkingUpdateForCurrentRemoteLocale = true; |
| 502 | + applyRemoteLanguage(currentLocaleInfo, currentLocaleInfo.baseLangCode, false, currentAccount, () -> { |
| 503 | + checkingUpdateForCurrentRemoteLocale = false; |
| 504 | + checkPatchLangpack(currentAccount); |
| 505 | + }); |
497 | 506 | }
|
498 | 507 | }
|
499 | 508 | if (currentLocaleInfo.version < version) {
|
500 |
| - applyRemoteLanguage(currentLocaleInfo, currentLocaleInfo.shortName, false, currentAccount, null); |
| 509 | + checkingUpdateForCurrentRemoteLocale = true; |
| 510 | + applyRemoteLanguage(currentLocaleInfo, currentLocaleInfo.shortName, false, currentAccount, () -> { |
| 511 | + checkingUpdateForCurrentRemoteLocale = false; |
| 512 | + checkPatchLangpack(currentAccount); |
| 513 | + }); |
| 514 | + } |
| 515 | + } |
| 516 | + |
| 517 | + public int calculateTranslatedCount(HashMap<String, String> map) { |
| 518 | + int count = 0; |
| 519 | + HashSet<String> added = new HashSet<>(); |
| 520 | + for (String k : map.keySet()) { |
| 521 | + if (k == null) { |
| 522 | + continue; |
| 523 | + } |
| 524 | + String real = null; |
| 525 | + if (k.endsWith("_other")) { |
| 526 | + real = k.substring(0, k.length() - 6); |
| 527 | + } else if (k.endsWith("_zero") || k.endsWith("_many")) { |
| 528 | + real = k.substring(0, k.length() - 5); |
| 529 | + } else if (k.endsWith("_one") || k.endsWith("_two") || k.endsWith("_few")) { |
| 530 | + real = k.substring(0, k.length() - 4); |
| 531 | + } |
| 532 | + if (real == null) { |
| 533 | + count++; |
| 534 | + } else if (!added.contains(real)) { |
| 535 | + added.add(real); |
| 536 | + count++; |
| 537 | + } |
| 538 | + } |
| 539 | + added.clear(); |
| 540 | + return count; |
| 541 | + } |
| 542 | + |
| 543 | + public void checkPatchLangpack(int currentAccount) { |
| 544 | + if (currentLocaleInfo == null || checkingUpdateForCurrentRemoteLocale) { |
| 545 | + return; |
| 546 | + } |
| 547 | + if (shouldReinstallLangpack(currentLocaleInfo.shortName)) { |
| 548 | + if (BuildVars.LOGS_ENABLED) { |
| 549 | + FileLog.d("reload locale because locale file is not enough"); |
| 550 | + } |
| 551 | + AndroidUtilities.runOnUIThread(() -> reloadCurrentRemoteLocale(currentAccount, null, true, null)); |
501 | 552 | }
|
502 | 553 | }
|
503 | 554 |
|
@@ -943,7 +994,7 @@ public int applyLanguage(final LocaleInfo localeInfo, boolean override, boolean
|
943 | 994 | config.locale = currentLocale;
|
944 | 995 | ApplicationLoader.applicationContext.getResources().updateConfiguration(config, ApplicationLoader.applicationContext.getResources().getDisplayMetrics());
|
945 | 996 | changingConfiguration = false;
|
946 |
| - if (reloadLastFile) { |
| 997 | + if (reloadLastFile || !isLoadingRemote && !force && shouldReinstallLangpack(localeInfo.shortName)) { |
947 | 998 | if (BuildVars.LOGS_ENABLED) {
|
948 | 999 | FileLog.d("reload locale because one of file is corrupted " + pathToFile + " " + pathToBaseFile);
|
949 | 1000 | }
|
@@ -2316,6 +2367,7 @@ private int applyRemoteLanguage(LocaleInfo localeInfo, String langCode, boolean
|
2316 | 2367 | onDone.run();
|
2317 | 2368 | }
|
2318 | 2369 | };
|
| 2370 | + patched(localeInfo.shortName); |
2319 | 2371 | if (localeInfo.hasBaseLang() && (langCode == null || langCode.equals(localeInfo.baseLangCode))) {
|
2320 | 2372 | if (localeInfo.baseVersion != 0 && !force) {
|
2321 | 2373 | if (localeInfo.hasBaseLang()) {
|
@@ -3261,6 +3313,25 @@ public static String formatDistance(float distance, int type) {
|
3261 | 3313 | return formatDistance(distance, type, null);
|
3262 | 3314 | }
|
3263 | 3315 |
|
| 3316 | + // patch to force reinstalling of langpack in case some strings are missing after 9.0 |
| 3317 | + private boolean shouldReinstallLangpack(String lng) { |
| 3318 | + int mustBeCount = MessagesController.getInstance(UserConfig.selectedAccount).checkResetLangpack; |
| 3319 | + if (mustBeCount <= 0) { |
| 3320 | + return false; |
| 3321 | + } |
| 3322 | + boolean alreadyPatched = MessagesController.getGlobalMainSettings().getBoolean("lngpack_patched_" + lng, false); |
| 3323 | + if (alreadyPatched) { |
| 3324 | + return false; |
| 3325 | + } |
| 3326 | + int count = calculateTranslatedCount(localeValues); |
| 3327 | + if (count >= mustBeCount) { |
| 3328 | + return false; |
| 3329 | + } |
| 3330 | + FileLog.e("reinstalling " + lng + " langpack because of patch (" + count + " keys, must be at least " + mustBeCount + ")"); |
| 3331 | + patched(lng); |
| 3332 | + return true; |
| 3333 | + } |
| 3334 | + |
3264 | 3335 | public static String formatDistance(float distance, int type, Boolean useImperial) {
|
3265 | 3336 | ensureImperialSystemInit();
|
3266 | 3337 | boolean imperial = useImperial != null && useImperial || useImperial == null && useImperialSystemType;
|
@@ -3324,4 +3395,11 @@ public static String formatDistance(float distance, int type, Boolean useImperia
|
3324 | 3395 | }
|
3325 | 3396 | }
|
3326 | 3397 | }
|
| 3398 | + |
| 3399 | + private void patched(String lng) { |
| 3400 | + if (BuildVars.LOGS_ENABLED) { |
| 3401 | + FileLog.d("set as patched " + lng + " langpack"); |
| 3402 | + } |
| 3403 | + MessagesController.getGlobalMainSettings().edit().putBoolean("lngpack_patched_" + lng, true).apply(); |
| 3404 | + } |
3327 | 3405 | }
|
0 commit comments