NekoX/TMessagesProj/src/main/java/org/telegram/messenger/LocaleController.java

3324 lines
139 KiB
Java
Raw Normal View History

/*
* This is the source code of Telegram for Android v. 1.3.x.
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
2019-01-23 18:03:33 +01:00
* Copyright Nikolai Kudashov, 2013-2018.
*/
2015-09-24 22:52:02 +02:00
package org.telegram.messenger;
2014-03-25 01:25:32 +01:00
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
2014-03-25 01:25:32 +01:00
import android.content.SharedPreferences;
2020-06-25 17:28:24 +02:00
import android.content.res.AssetManager;
2014-03-25 01:25:32 +01:00
import android.content.res.Configuration;
2021-11-17 16:02:31 +01:00
import android.content.res.Resources;
import android.os.Build;
2019-07-18 15:01:39 +02:00
import android.telephony.TelephonyManager;
2017-07-08 18:32:04 +02:00
import android.text.TextUtils;
2014-03-25 01:25:32 +01:00
import android.text.format.DateFormat;
import android.util.Xml;
2020-06-25 17:28:24 +02:00
import android.view.Gravity;
2014-03-25 01:25:32 +01:00
import com.google.gson.Gson;
import com.google.gson.JsonObject;
2020-06-25 17:28:24 +02:00
import org.telegram.messenger.support.ArrayUtils;
2015-09-24 22:52:02 +02:00
import org.telegram.messenger.time.FastDateFormat;
import org.telegram.tgnet.ConnectionsManager;
2017-07-08 18:32:04 +02:00
import org.telegram.tgnet.TLObject;
2015-09-24 22:52:02 +02:00
import org.telegram.tgnet.TLRPC;
import org.xmlpull.v1.XmlPullParser;
2017-07-08 18:32:04 +02:00
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
2017-07-08 18:32:04 +02:00
import java.io.FileWriter;
2020-06-25 17:28:24 +02:00
import java.io.IOException;
2017-03-31 01:58:05 +02:00
import java.text.NumberFormat;
2014-03-25 01:25:32 +01:00
import java.util.ArrayList;
import java.util.Calendar;
2021-12-30 11:52:40 +01:00
import java.util.Collection;
2017-03-31 01:58:05 +02:00
import java.util.Currency;
2014-03-25 01:25:32 +01:00
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
2021-12-30 11:52:40 +01:00
import java.util.Map;
import java.util.TimeZone;
2021-10-30 08:05:57 +02:00
import tw.nekomimi.nkmr.NekomuraConfig;
2021-01-31 18:28:28 +01:00
import tw.nekomimi.nekogram.parts.LocFiltersKt;
2021-04-01 02:48:10 +02:00
import tw.nekomimi.nekogram.shamsicalendar.PersianCalendar;
2020-06-25 17:28:24 +02:00
import tw.nekomimi.nekogram.utils.FileUtil;
import tw.nekomimi.nekogram.utils.GsonUtil;
2019-06-19 15:42:55 +02:00
public class LocaleController {
2014-07-03 16:55:04 +02:00
static final int QUANTITY_OTHER = 0x0000;
static final int QUANTITY_ZERO = 0x0001;
static final int QUANTITY_ONE = 0x0002;
static final int QUANTITY_TWO = 0x0004;
static final int QUANTITY_FEW = 0x0008;
static final int QUANTITY_MANY = 0x0010;
2014-03-25 01:25:32 +01:00
public static boolean isRTL = false;
2020-06-25 17:28:24 +02:00
public static int generateFlagStart() {
return isRTL ? Gravity.RIGHT : Gravity.LEFT;
}
2018-07-30 04:07:02 +02:00
public static boolean is24HourFormat = false;
2015-11-26 22:04:02 +01:00
public FastDateFormat formatterDay;
public FastDateFormat formatterWeek;
2020-09-30 15:48:47 +02:00
public FastDateFormat formatterWeekLong;
2019-01-23 18:03:33 +01:00
public FastDateFormat formatterDayMonth;
2015-11-26 22:04:02 +01:00
public FastDateFormat formatterYear;
public FastDateFormat formatterYearMax;
2017-03-31 01:58:05 +02:00
public FastDateFormat formatterStats;
2017-07-08 18:32:04 +02:00
public FastDateFormat formatterBannedUntil;
public FastDateFormat formatterBannedUntilThisYear;
2015-11-26 22:04:02 +01:00
public FastDateFormat chatDate;
public FastDateFormat chatFullDate;
2019-01-23 18:03:33 +01:00
public FastDateFormat formatterScheduleDay;
2019-09-10 12:56:11 +02:00
public FastDateFormat formatterScheduleYear;
2020-09-30 15:48:47 +02:00
public FastDateFormat formatterMonthYear;
2021-04-14 03:44:46 +02:00
public FastDateFormat[] formatterScheduleSend = new FastDateFormat[15];
2014-03-25 01:25:32 +01:00
2015-02-01 19:51:02 +01:00
private HashMap<String, PluralRules> allRules = new HashMap<>();
2014-07-03 16:55:04 +02:00
2020-02-11 06:26:46 +01:00
public Locale currentLocale;
2014-03-25 01:25:32 +01:00
private Locale systemDefaultLocale;
2014-07-03 16:55:04 +02:00
private PluralRules currentPluralRules;
2014-03-25 01:25:32 +01:00
private LocaleInfo currentLocaleInfo;
2015-02-01 19:51:02 +01:00
private HashMap<String, String> localeValues = new HashMap<>();
2014-03-25 01:25:32 +01:00
private String languageOverride;
private boolean changingConfiguration = false;
2017-07-08 18:32:04 +02:00
private boolean reloadLastFile;
2014-03-25 01:25:32 +01:00
2019-01-23 18:03:33 +01:00
private String currentSystemLocale;
2017-03-31 01:58:05 +02:00
private HashMap<String, String> currencyValues;
2015-02-01 19:51:02 +01:00
private HashMap<String, String> translitChars;
2019-05-14 14:08:05 +02:00
private HashMap<String, String> ruTranslitChars;
2015-02-01 19:51:02 +01:00
2021-11-17 15:17:21 +01:00
public static boolean usePersianCalendar = NekomuraConfig.usePersianCalendar.Bool(); // need restart
2021-04-01 04:06:54 +02:00
private class TimeZoneChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
2018-08-27 10:33:11 +02:00
ApplicationLoader.applicationHandler.post(() -> {
2019-01-23 18:03:33 +01:00
if (!formatterDayMonth.getTimeZone().equals(TimeZone.getDefault())) {
2018-08-27 10:33:11 +02:00
LocaleController.getInstance().recreateFormatters();
}
});
}
}
2014-03-25 01:25:32 +01:00
public static class LocaleInfo {
2017-07-08 18:32:04 +02:00
2014-03-25 01:25:32 +01:00
public String name;
public String nameEnglish;
public String shortName;
public String pathToFile;
2019-01-23 18:03:33 +01:00
public String baseLangCode;
public String pluralLangCode;
public boolean isRtl;
2017-07-08 18:32:04 +02:00
public int version;
2019-01-23 18:03:33 +01:00
public int baseVersion;
2017-07-08 18:32:04 +02:00
public boolean builtIn;
2019-01-23 18:03:33 +01:00
public int serverIndex;
2020-06-25 17:28:24 +02:00
public TLRPC.TL_langPackLanguage pack;
public boolean toInstall;
public String getSaveString() {
2019-01-23 18:03:33 +01:00
String langCode = baseLangCode == null ? "" : baseLangCode;
String pluralCode = TextUtils.isEmpty(pluralLangCode) ? shortName : pluralLangCode;
return name + "|" + nameEnglish + "|" + shortName + "|" + pathToFile + "|" + version + "|" + langCode + "|" + pluralLangCode + "|" + (isRtl ? 1 : 0) + "|" + baseVersion + "|" + serverIndex;
}
public static LocaleInfo createWithString(String string) {
if (string == null || string.length() == 0) {
return null;
}
String[] args = string.split("\\|");
2017-07-08 18:32:04 +02:00
LocaleInfo localeInfo = null;
if (args.length >= 4) {
localeInfo = new LocaleInfo();
localeInfo.name = args[0];
localeInfo.nameEnglish = args[1];
2017-12-08 18:35:59 +01:00
localeInfo.shortName = args[2].toLowerCase();
2017-07-08 18:32:04 +02:00
localeInfo.pathToFile = args[3];
if (args.length >= 5) {
localeInfo.version = Utilities.parseInt(args[4]);
}
2019-01-23 18:03:33 +01:00
localeInfo.baseLangCode = args.length >= 6 ? args[5] : "";
localeInfo.pluralLangCode = args.length >= 7 ? args[6] : localeInfo.shortName;
if (args.length >= 8) {
localeInfo.isRtl = Utilities.parseInt(args[7]) == 1;
}
if (args.length >= 9) {
localeInfo.baseVersion = Utilities.parseInt(args[8]);
}
if (args.length >= 10) {
localeInfo.serverIndex = Utilities.parseInt(args[9]);
} else {
localeInfo.serverIndex = Integer.MAX_VALUE;
}
if (!TextUtils.isEmpty(localeInfo.baseLangCode)) {
localeInfo.baseLangCode = localeInfo.baseLangCode.replace("-", "_");
}
}
return localeInfo;
}
2017-07-08 18:32:04 +02:00
public File getPathToFile() {
2020-06-25 17:28:24 +02:00
File baseDir = new File(ApplicationLoader.getDataDirFixed(), "languages");
FileUtil.initDir(baseDir);
2017-07-08 18:32:04 +02:00
if (isRemote()) {
2020-06-25 17:28:24 +02:00
return new File(baseDir, "remote_" + shortName + ".xml");
2019-01-23 18:03:33 +01:00
} else if (isUnofficial()) {
2020-06-25 17:28:24 +02:00
return new File(baseDir, "unofficial_" + shortName + ".xml");
2017-07-08 18:32:04 +02:00
}
return !TextUtils.isEmpty(pathToFile) ? new File(pathToFile) : null;
}
2019-01-23 18:03:33 +01:00
public File getPathToBaseFile() {
if (isUnofficial()) {
2020-06-25 17:28:24 +02:00
File baseDir = new File(ApplicationLoader.getDataDirFixed(), "languages");
FileUtil.initDir(baseDir);
return new File(baseDir, "unofficial_base_" + shortName + ".xml");
2019-01-23 18:03:33 +01:00
}
return null;
}
2017-07-08 18:32:04 +02:00
public String getKey() {
2019-01-23 18:03:33 +01:00
if (pathToFile != null && !isRemote() && !isUnofficial()) {
2017-07-08 18:32:04 +02:00
return "local_" + shortName;
2019-01-23 18:03:33 +01:00
} else if (isUnofficial()) {
return "unofficial_" + shortName;
2017-07-08 18:32:04 +02:00
}
return shortName;
}
2019-01-23 18:03:33 +01:00
public boolean hasBaseLang() {
return isUnofficial() && !TextUtils.isEmpty(baseLangCode) && !baseLangCode.equals(shortName);
}
2017-07-08 18:32:04 +02:00
public boolean isRemote() {
return "remote".equals(pathToFile);
}
2019-01-23 18:03:33 +01:00
public boolean isUnofficial() {
return "unofficial".equals(pathToFile);
}
2017-07-08 18:32:04 +02:00
public boolean isLocal() {
2019-01-23 18:03:33 +01:00
return !TextUtils.isEmpty(pathToFile) && !isRemote() && !isUnofficial();
2017-07-08 18:32:04 +02:00
}
public boolean isBuiltIn() {
return builtIn;
}
2019-01-23 18:03:33 +01:00
public String getLangCode() {
return shortName.replace("_", "-");
}
public String getBaseLangCode() {
return baseLangCode == null ? "" : baseLangCode.replace("_", "-");
}
2014-03-25 01:25:32 +01:00
}
2017-07-08 18:32:04 +02:00
private boolean loadingRemoteLanguages;
public ArrayList<LocaleInfo> languages = new ArrayList<>();
2019-01-23 18:03:33 +01:00
public ArrayList<LocaleInfo> unofficialLanguages = new ArrayList<>();
2017-07-08 18:32:04 +02:00
public ArrayList<LocaleInfo> remoteLanguages = new ArrayList<>();
2019-01-23 18:03:33 +01:00
public HashMap<String, LocaleInfo> remoteLanguagesDict = new HashMap<>();
2015-02-01 19:51:02 +01:00
public HashMap<String, LocaleInfo> languagesDict = new HashMap<>();
2015-02-01 19:51:02 +01:00
private ArrayList<LocaleInfo> otherLanguages = new ArrayList<>();
private static volatile LocaleController Instance = null;
2020-06-25 17:28:24 +02:00
public static LocaleController getInstance() {
LocaleController localInstance = Instance;
if (localInstance == null) {
synchronized (LocaleController.class) {
localInstance = Instance;
if (localInstance == null) {
Instance = localInstance = new LocaleController();
}
}
}
return localInstance;
}
public LocaleController() {
2014-07-03 16:55:04 +02:00
addRules(new String[]{"bem", "brx", "da", "de", "el", "en", "eo", "es", "et", "fi", "fo", "gl", "he", "iw", "it", "nb",
"nl", "nn", "no", "sv", "af", "bg", "bn", "ca", "eu", "fur", "fy", "gu", "ha", "is", "ku",
"lb", "ml", "mr", "nah", "ne", "om", "or", "pa", "pap", "ps", "so", "sq", "sw", "ta", "te",
"tk", "ur", "zu", "mn", "gsw", "chr", "rm", "pt", "an", "ast"}, new PluralRules_One());
2020-10-31 22:13:37 +01:00
addRules(new String[]{"cs", "sk"}, new PluralRules_Czech());
2014-07-03 16:55:04 +02:00
addRules(new String[]{"ff", "fr", "kab"}, new PluralRules_French());
2020-12-23 08:48:30 +01:00
addRules(new String[]{"ru", "uk", "be"}, new PluralRules_Balkan());
addRules(new String[]{"sr", "hr", "bs", "sh"}, new PluralRules_Serbian());
2014-07-03 16:55:04 +02:00
addRules(new String[]{"lv"}, new PluralRules_Latvian());
addRules(new String[]{"lt"}, new PluralRules_Lithuanian());
addRules(new String[]{"pl"}, new PluralRules_Polish());
addRules(new String[]{"ro", "mo"}, new PluralRules_Romanian());
addRules(new String[]{"sl"}, new PluralRules_Slovenian());
addRules(new String[]{"ar"}, new PluralRules_Arabic());
addRules(new String[]{"mk"}, new PluralRules_Macedonian());
addRules(new String[]{"cy"}, new PluralRules_Welsh());
addRules(new String[]{"br"}, new PluralRules_Breton());
addRules(new String[]{"lag"}, new PluralRules_Langi());
addRules(new String[]{"shi"}, new PluralRules_Tachelhit());
addRules(new String[]{"mt"}, new PluralRules_Maltese());
addRules(new String[]{"ga", "se", "sma", "smi", "smj", "smn", "sms"}, new PluralRules_Two());
addRules(new String[]{"ak", "am", "bh", "fil", "tl", "guw", "hi", "ln", "mg", "nso", "ti", "wa"}, new PluralRules_Zero());
addRules(new String[]{"az", "bm", "fa", "ig", "hu", "ja", "kde", "kea", "ko", "my", "ses", "sg", "to",
2017-12-08 18:35:59 +01:00
"tr", "vi", "wo", "yo", "zh", "bo", "dz", "id", "jv", "jw", "ka", "km", "kn", "ms", "th", "in"}, new PluralRules_None());
2014-07-03 16:55:04 +02:00
LocaleInfo localeInfo = new LocaleInfo();
2014-03-25 01:25:32 +01:00
localeInfo.name = "English";
localeInfo.nameEnglish = "English";
2019-01-23 18:03:33 +01:00
localeInfo.shortName = localeInfo.pluralLangCode = "en";
localeInfo.pathToFile = null;
2017-07-08 18:32:04 +02:00
localeInfo.builtIn = true;
languages.add(localeInfo);
2014-03-25 01:25:32 +01:00
languagesDict.put(localeInfo.shortName, localeInfo);
localeInfo = new LocaleInfo();
2014-03-25 01:25:32 +01:00
localeInfo.name = "Italiano";
localeInfo.nameEnglish = "Italian";
2019-01-23 18:03:33 +01:00
localeInfo.shortName = localeInfo.pluralLangCode = "it";
localeInfo.pathToFile = null;
2017-07-08 18:32:04 +02:00
localeInfo.builtIn = true;
languages.add(localeInfo);
2014-03-25 01:25:32 +01:00
languagesDict.put(localeInfo.shortName, localeInfo);
localeInfo = new LocaleInfo();
2014-03-25 01:25:32 +01:00
localeInfo.name = "Español";
localeInfo.nameEnglish = "Spanish";
2019-01-23 18:03:33 +01:00
localeInfo.shortName = localeInfo.pluralLangCode = "es";
2017-07-08 18:32:04 +02:00
localeInfo.builtIn = true;
languages.add(localeInfo);
2014-03-25 01:25:32 +01:00
languagesDict.put(localeInfo.shortName, localeInfo);
localeInfo = new LocaleInfo();
2014-03-25 01:25:32 +01:00
localeInfo.name = "Deutsch";
localeInfo.nameEnglish = "German";
2019-01-23 18:03:33 +01:00
localeInfo.shortName = localeInfo.pluralLangCode = "de";
localeInfo.pathToFile = null;
2017-07-08 18:32:04 +02:00
localeInfo.builtIn = true;
languages.add(localeInfo);
2014-03-25 01:25:32 +01:00
languagesDict.put(localeInfo.shortName, localeInfo);
localeInfo = new LocaleInfo();
2014-03-25 01:25:32 +01:00
localeInfo.name = "Nederlands";
localeInfo.nameEnglish = "Dutch";
2019-01-23 18:03:33 +01:00
localeInfo.shortName = localeInfo.pluralLangCode = "nl";
localeInfo.pathToFile = null;
2017-07-08 18:32:04 +02:00
localeInfo.builtIn = true;
languages.add(localeInfo);
2014-03-25 01:25:32 +01:00
languagesDict.put(localeInfo.shortName, localeInfo);
localeInfo = new LocaleInfo();
2014-03-25 01:25:32 +01:00
localeInfo.name = "العربية";
localeInfo.nameEnglish = "Arabic";
2019-01-23 18:03:33 +01:00
localeInfo.shortName = localeInfo.pluralLangCode = "ar";
localeInfo.pathToFile = null;
2017-07-08 18:32:04 +02:00
localeInfo.builtIn = true;
2019-01-23 18:03:33 +01:00
localeInfo.isRtl = true;
2017-07-08 18:32:04 +02:00
languages.add(localeInfo);
2014-03-25 01:25:32 +01:00
languagesDict.put(localeInfo.shortName, localeInfo);
2014-06-13 00:37:05 +02:00
localeInfo = new LocaleInfo();
localeInfo.name = "Português (Brasil)";
localeInfo.nameEnglish = "Portuguese (Brazil)";
2019-01-23 18:03:33 +01:00
localeInfo.shortName = localeInfo.pluralLangCode = "pt_br";
2014-06-13 00:37:05 +02:00
localeInfo.pathToFile = null;
2017-07-08 18:32:04 +02:00
localeInfo.builtIn = true;
languages.add(localeInfo);
2014-06-13 00:37:05 +02:00
languagesDict.put(localeInfo.shortName, localeInfo);
2014-10-06 12:38:00 +02:00
localeInfo = new LocaleInfo();
localeInfo.name = "한국어";
localeInfo.nameEnglish = "Korean";
2019-01-23 18:03:33 +01:00
localeInfo.shortName = localeInfo.pluralLangCode = "ko";
2014-10-06 12:38:00 +02:00
localeInfo.pathToFile = null;
2017-07-08 18:32:04 +02:00
localeInfo.builtIn = true;
languages.add(localeInfo);
2014-10-06 12:38:00 +02:00
languagesDict.put(localeInfo.shortName, localeInfo);
2021-04-01 03:07:40 +02:00
localeInfo = new LocaleInfo();
localeInfo.name = "فارسی";
localeInfo.nameEnglish = "Persian";
localeInfo.shortName = localeInfo.pluralLangCode = "fa";
localeInfo.pathToFile = null;
localeInfo.builtIn = true;
localeInfo.isRtl = true;
languages.add(localeInfo);
languagesDict.put(localeInfo.shortName, localeInfo);
2014-10-06 12:38:00 +02:00
2019-06-17 05:54:01 +02:00
localeInfo = new LocaleInfo();
2020-09-23 15:52:07 +02:00
localeInfo.name = "简体中文";
2021-03-16 14:59:44 +01:00
localeInfo.nameEnglish = "Simplified Chinese";
2020-09-23 15:52:07 +02:00
localeInfo.shortName = "moecn";
2019-06-17 05:54:01 +02:00
localeInfo.baseLangCode = "zh_hans_raw";
localeInfo.isRtl = false;
localeInfo.pathToFile = "unofficial";
2020-06-25 17:28:24 +02:00
localeInfo.pluralLangCode = "zh_cn";
2019-06-17 05:54:01 +02:00
localeInfo.builtIn = true;
languages.add(localeInfo);
languagesDict.put(localeInfo.getKey(), localeInfo);
languagesDict.put("zh_cn", localeInfo);
2019-07-29 17:22:30 +02:00
languagesDict.put("zh_sg", localeInfo);
2019-06-17 05:54:01 +02:00
localeInfo = new LocaleInfo();
localeInfo.name = "正體中文";
localeInfo.nameEnglish = "Chinese (zh-Hant-TW)";
localeInfo.shortName = "taiwan";
localeInfo.baseLangCode = "zh_hant_raw";
localeInfo.isRtl = false;
localeInfo.pathToFile = "unofficial";
2020-02-11 06:26:46 +01:00
localeInfo.pluralLangCode = "zh_tw";
2019-06-17 05:54:01 +02:00
localeInfo.builtIn = true;
languages.add(localeInfo);
languagesDict.put(localeInfo.getKey(), localeInfo);
2020-06-25 17:28:24 +02:00
languagesDict.put("zh_tw", localeInfo);
languagesDict.put("zh_hk", localeInfo);
languagesDict.put("zh_mo", localeInfo);
2019-06-17 05:54:01 +02:00
localeInfo = new LocaleInfo();
localeInfo.name = "日本語";
localeInfo.nameEnglish = "Japanese";
localeInfo.shortName = "ja_raw";
localeInfo.baseLangCode = null;
localeInfo.isRtl = false;
localeInfo.pathToFile = "unofficial";
localeInfo.pluralLangCode = "ja";
localeInfo.builtIn = true;
languages.add(localeInfo);
languagesDict.put(localeInfo.getKey(), localeInfo);
languagesDict.put("ja", localeInfo);
loadOtherLanguages();
2017-07-08 18:32:04 +02:00
if (remoteLanguages.isEmpty()) {
2018-08-27 10:33:11 +02:00
AndroidUtilities.runOnUIThread(() -> loadRemoteLanguages(UserConfig.selectedAccount));
2017-07-08 18:32:04 +02:00
}
2017-07-08 18:32:04 +02:00
for (int a = 0; a < otherLanguages.size(); a++) {
LocaleInfo locale = otherLanguages.get(a);
languages.add(locale);
languagesDict.put(locale.getKey(), locale);
}
2017-07-08 18:32:04 +02:00
for (int a = 0; a < remoteLanguages.size(); a++) {
LocaleInfo locale = remoteLanguages.get(a);
LocaleInfo existingLocale = getLanguageFromDict(locale.getKey());
if (existingLocale != null) {
existingLocale.pathToFile = locale.pathToFile;
existingLocale.version = locale.version;
2019-01-23 18:03:33 +01:00
existingLocale.baseVersion = locale.baseVersion;
existingLocale.serverIndex = locale.serverIndex;
2018-07-30 04:07:02 +02:00
remoteLanguages.set(a, existingLocale);
2017-07-08 18:32:04 +02:00
} else {
languages.add(locale);
languagesDict.put(locale.getKey(), locale);
2014-03-25 01:25:32 +01:00
}
2017-07-08 18:32:04 +02:00
}
2014-03-25 01:25:32 +01:00
2019-01-23 18:03:33 +01:00
for (int a = 0; a < unofficialLanguages.size(); a++) {
LocaleInfo locale = unofficialLanguages.get(a);
LocaleInfo existingLocale = getLanguageFromDict(locale.getKey());
if (existingLocale != null) {
existingLocale.pathToFile = locale.pathToFile;
existingLocale.version = locale.version;
existingLocale.baseVersion = locale.baseVersion;
existingLocale.serverIndex = locale.serverIndex;
unofficialLanguages.set(a, existingLocale);
} else {
languagesDict.put(locale.getKey(), locale);
}
}
2014-03-25 01:25:32 +01:00
systemDefaultLocale = Locale.getDefault();
is24HourFormat = DateFormat.is24HourFormat(ApplicationLoader.applicationContext);
2014-03-25 01:25:32 +01:00
2021-03-12 13:37:39 +01:00
Utilities.stageQueue.postRunnable(() -> {
LocaleInfo currentInfo = null;
boolean override = false;
try {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
String lang = preferences.getString("language", null);
if (lang != null) {
currentInfo = getLanguageFromDict(lang);
if (currentInfo != null) {
override = true;
}
2014-03-25 01:25:32 +01:00
}
2021-03-12 13:37:39 +01:00
if (currentInfo == null && systemDefaultLocale.getLanguage() != null) {
currentInfo = getLanguageFromDict(systemDefaultLocale.getLanguage());
}
2017-07-08 18:32:04 +02:00
if (currentInfo == null) {
2021-03-12 13:37:39 +01:00
currentInfo = getLanguageFromDict(getLocaleString(systemDefaultLocale));
if (currentInfo == null) {
currentInfo = getLanguageFromDict("en");
}
2017-07-08 18:32:04 +02:00
}
2021-03-12 13:37:39 +01:00
applyLanguage(currentInfo, override, true, UserConfig.selectedAccount);
} catch (Exception e) {
FileLog.e(e);
2014-03-25 01:25:32 +01:00
}
2017-07-08 18:32:04 +02:00
2021-03-12 13:37:39 +01:00
try {
IntentFilter timezoneFilter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED);
ApplicationLoader.applicationContext.registerReceiver(new TimeZoneChangedReceiver(), timezoneFilter);
} catch (Exception e) {
FileLog.e(e);
}
2021-03-12 13:37:39 +01:00
AndroidUtilities.runOnUIThread(() -> currentSystemLocale = getSystemLocaleStringIso639());
});
2019-01-23 18:03:33 +01:00
}
2019-01-23 18:03:33 +01:00
public LocaleInfo getLanguageFromDict(String key) {
2017-07-08 18:32:04 +02:00
if (key == null) {
return null;
}
return languagesDict.get(key.toLowerCase().replace("-", "_"));
}
2021-12-30 11:52:40 +01:00
public LocaleInfo getLanguageByPlural(String plural) {
Collection<LocaleInfo> values = languagesDict.values();
for (LocaleInfo l : values)
if (l.pluralLangCode != null && l.pluralLangCode.equals(plural))
return l;
return null;
}
2017-07-08 18:32:04 +02:00
2014-07-03 16:55:04 +02:00
private void addRules(String[] languages, PluralRules rules) {
for (String language : languages) {
allRules.put(language, rules);
}
}
private String stringForQuantity(int quantity) {
switch (quantity) {
case QUANTITY_ZERO:
return "zero";
case QUANTITY_ONE:
return "one";
case QUANTITY_TWO:
return "two";
case QUANTITY_FEW:
return "few";
case QUANTITY_MANY:
return "many";
default:
return "other";
}
}
public Locale getSystemDefaultLocale() {
return systemDefaultLocale;
}
2017-07-08 18:32:04 +02:00
public boolean isCurrentLocalLocale() {
return currentLocaleInfo.isLocal();
}
2020-03-30 14:00:09 +02:00
public void reloadCurrentRemoteLocale(int currentAccount, String langCode, boolean force) {
2019-01-23 18:03:33 +01:00
if (langCode != null) {
langCode = langCode.replace("-", "_");
}
if (langCode == null || currentLocaleInfo != null && (langCode.equals(currentLocaleInfo.shortName) || langCode.equals(currentLocaleInfo.baseLangCode))) {
2020-03-30 14:00:09 +02:00
applyRemoteLanguage(currentLocaleInfo, langCode, force, currentAccount);
2019-01-23 18:03:33 +01:00
}
2018-07-30 04:07:02 +02:00
}
2019-01-23 18:03:33 +01:00
public void checkUpdateForCurrentRemoteLocale(int currentAccount, int version, int baseVersion) {
2021-09-20 00:10:42 +02:00
if (currentLocaleInfo == null || !currentLocaleInfo.isRemote() && !currentLocaleInfo.isUnofficial()) {
2018-07-30 04:07:02 +02:00
return;
}
2019-01-23 18:03:33 +01:00
if (currentLocaleInfo.hasBaseLang()) {
if (currentLocaleInfo.baseVersion < baseVersion) {
applyRemoteLanguage(currentLocaleInfo, currentLocaleInfo.baseLangCode, false, currentAccount);
}
}
2018-07-30 04:07:02 +02:00
if (currentLocaleInfo.version < version) {
2019-01-23 18:03:33 +01:00
applyRemoteLanguage(currentLocaleInfo, currentLocaleInfo.shortName, false, currentAccount);
2018-07-30 04:07:02 +02:00
}
2017-07-08 18:32:04 +02:00
}
2016-04-22 15:49:00 +02:00
private String getLocaleString(Locale locale) {
if (locale == null) {
return "en";
}
String languageCode = locale.getLanguage();
String countryCode = locale.getCountry();
String variantCode = locale.getVariant();
if (languageCode.length() == 0 && countryCode.length() == 0) {
return "en";
}
StringBuilder result = new StringBuilder(11);
result.append(languageCode);
if (countryCode.length() > 0 || variantCode.length() > 0) {
result.append('_');
}
result.append(countryCode);
if (variantCode.length() > 0) {
result.append('_');
}
result.append(variantCode);
return result.toString();
}
2021-03-12 13:37:39 +01:00
private static String cached639;
2017-07-08 18:32:04 +02:00
public static String getSystemLocaleStringIso639() {
2021-03-12 13:37:39 +01:00
if (cached639 != null) return cached639;
2016-04-22 15:49:00 +02:00
Locale locale = getInstance().getSystemDefaultLocale();
if (locale == null) {
return "en";
}
String languageCode = locale.getLanguage();
String countryCode = locale.getCountry();
String variantCode = locale.getVariant();
if (languageCode.length() == 0 && countryCode.length() == 0) {
return "en";
}
StringBuilder result = new StringBuilder(11);
result.append(languageCode);
if (countryCode.length() > 0 || variantCode.length() > 0) {
2016-03-16 13:26:32 +01:00
result.append('-');
}
result.append(countryCode);
if (variantCode.length() > 0) {
result.append('_');
}
result.append(variantCode);
2021-03-12 13:37:39 +01:00
cached639 = result.toString();
return cached639;
}
2017-07-08 18:32:04 +02:00
public static String getLocaleStringIso639() {
2019-07-18 15:01:39 +02:00
LocaleInfo info = getInstance().currentLocaleInfo;
if (info != null) {
return info.getLangCode();
}
2017-07-08 18:32:04 +02:00
Locale locale = getInstance().currentLocale;
if (locale == null) {
return "en";
}
String languageCode = locale.getLanguage();
String countryCode = locale.getCountry();
String variantCode = locale.getVariant();
if (languageCode.length() == 0 && countryCode.length() == 0) {
return "en";
}
StringBuilder result = new StringBuilder(11);
result.append(languageCode);
if (countryCode.length() > 0 || variantCode.length() > 0) {
result.append('-');
}
result.append(countryCode);
if (variantCode.length() > 0) {
result.append('_');
}
result.append(variantCode);
return result.toString();
}
2017-12-08 18:35:59 +01:00
public static String getLocaleAlias(String code) {
if (code == null) {
return null;
}
switch (code) {
case "in":
return "id";
case "iw":
return "he";
case "jw":
return "jv";
case "no":
return "nb";
case "tl":
return "fil";
case "ji":
return "yi";
case "id":
return "in";
case "he":
return "iw";
case "jv":
return "jw";
case "nb":
return "no";
case "fil":
return "tl";
case "yi":
return "ji";
}
return null;
}
2018-07-30 04:07:02 +02:00
public boolean applyLanguageFile(File file, int currentAccount) {
try {
HashMap<String, String> stringMap = getLocaleFileStrings(file);
String languageName = stringMap.get("LanguageName");
String languageNameInEnglish = stringMap.get("LanguageNameInEnglish");
String languageCode = stringMap.get("LanguageCode");
if (languageName != null && languageName.length() > 0 &&
languageNameInEnglish != null && languageNameInEnglish.length() > 0 &&
languageCode != null && languageCode.length() > 0) {
if (languageName.contains("&") || languageName.contains("|")) {
return false;
}
if (languageNameInEnglish.contains("&") || languageNameInEnglish.contains("|")) {
return false;
}
2016-05-25 23:49:47 +02:00
if (languageCode.contains("&") || languageCode.contains("|") || languageCode.contains("/") || languageCode.contains("\\")) {
return false;
}
2015-10-29 18:10:07 +01:00
File finalFile = new File(ApplicationLoader.getFilesDirFixed(), languageCode + ".xml");
2015-05-21 23:27:27 +02:00
if (!AndroidUtilities.copyFile(file, finalFile)) {
return false;
}
2018-07-30 04:07:02 +02:00
String key = "local_" + languageCode.toLowerCase();
LocaleInfo localeInfo = getLanguageFromDict(key);
if (localeInfo == null) {
localeInfo = new LocaleInfo();
localeInfo.name = languageName;
localeInfo.nameEnglish = languageNameInEnglish;
2017-12-08 18:35:59 +01:00
localeInfo.shortName = languageCode.toLowerCase();
2019-01-23 18:03:33 +01:00
localeInfo.pluralLangCode = localeInfo.shortName;
localeInfo.pathToFile = finalFile.getAbsolutePath();
2017-07-08 18:32:04 +02:00
languages.add(localeInfo);
2017-12-08 18:35:59 +01:00
languagesDict.put(localeInfo.getKey(), localeInfo);
otherLanguages.add(localeInfo);
saveOtherLanguages();
}
localeValues = stringMap;
2018-07-30 04:07:02 +02:00
applyLanguage(localeInfo, true, false, true, false, currentAccount);
return true;
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
}
return false;
}
private void saveOtherLanguages() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("langconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
2017-07-08 18:32:04 +02:00
StringBuilder stringBuilder = new StringBuilder();
for (int a = 0; a < otherLanguages.size(); a++) {
LocaleInfo localeInfo = otherLanguages.get(a);
String loc = localeInfo.getSaveString();
if (loc != null) {
if (stringBuilder.length() != 0) {
stringBuilder.append("&");
}
stringBuilder.append(loc);
}
}
editor.putString("locales", stringBuilder.toString());
stringBuilder.setLength(0);
for (int a = 0; a < remoteLanguages.size(); a++) {
LocaleInfo localeInfo = remoteLanguages.get(a);
String loc = localeInfo.getSaveString();
if (loc != null) {
2017-07-08 18:32:04 +02:00
if (stringBuilder.length() != 0) {
stringBuilder.append("&");
}
2017-07-08 18:32:04 +02:00
stringBuilder.append(loc);
}
}
2017-07-08 18:32:04 +02:00
editor.putString("remote", stringBuilder.toString());
2019-01-23 18:03:33 +01:00
stringBuilder.setLength(0);
for (int a = 0; a < unofficialLanguages.size(); a++) {
LocaleInfo localeInfo = unofficialLanguages.get(a);
String loc = localeInfo.getSaveString();
if (loc != null) {
if (stringBuilder.length() != 0) {
stringBuilder.append("&");
}
stringBuilder.append(loc);
}
}
editor.putString("unofficial", stringBuilder.toString());
2020-06-25 17:28:24 +02:00
editor.apply();
}
2018-07-30 04:07:02 +02:00
public boolean deleteLanguage(LocaleInfo localeInfo, int currentAccount) {
2019-01-23 18:03:33 +01:00
if (localeInfo.pathToFile == null || localeInfo.isRemote() && localeInfo.serverIndex != Integer.MAX_VALUE) {
return false;
}
if (currentLocaleInfo == localeInfo) {
2017-07-08 18:32:04 +02:00
LocaleInfo info = null;
if (systemDefaultLocale.getLanguage() != null) {
info = getLanguageFromDict(systemDefaultLocale.getLanguage());
}
if (info == null) {
info = getLanguageFromDict(getLocaleString(systemDefaultLocale));
}
if (info == null) {
info = getLanguageFromDict("en");
}
2018-07-30 04:07:02 +02:00
applyLanguage(info, true, false, currentAccount);
}
2019-01-23 18:03:33 +01:00
unofficialLanguages.remove(localeInfo);
remoteLanguages.remove(localeInfo);
remoteLanguagesDict.remove(localeInfo.getKey());
otherLanguages.remove(localeInfo);
2017-07-08 18:32:04 +02:00
languages.remove(localeInfo);
2019-01-23 18:03:33 +01:00
languagesDict.remove(localeInfo.getKey());
File file = new File(localeInfo.pathToFile);
file.delete();
saveOtherLanguages();
return true;
}
private void loadOtherLanguages() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("langconfig", Activity.MODE_PRIVATE);
String locales = preferences.getString("locales", null);
2017-07-08 18:32:04 +02:00
if (!TextUtils.isEmpty(locales)) {
String[] localesArr = locales.split("&");
for (String locale : localesArr) {
LocaleInfo localeInfo = LocaleInfo.createWithString(locale);
if (localeInfo != null) {
otherLanguages.add(localeInfo);
}
}
}
2017-07-08 18:32:04 +02:00
locales = preferences.getString("remote", null);
if (!TextUtils.isEmpty(locales)) {
String[] localesArr = locales.split("&");
for (String locale : localesArr) {
LocaleInfo localeInfo = LocaleInfo.createWithString(locale);
localeInfo.shortName = localeInfo.shortName.replace("-", "_");
2019-01-23 18:03:33 +01:00
if (remoteLanguagesDict.containsKey(localeInfo.getKey())) {
continue;
}
2021-09-20 00:10:42 +02:00
remoteLanguages.add(localeInfo);
remoteLanguagesDict.put(localeInfo.getKey(), localeInfo);
2019-01-23 18:03:33 +01:00
}
}
locales = preferences.getString("unofficial", null);
if (!TextUtils.isEmpty(locales)) {
String[] localesArr = locales.split("&");
for (String locale : localesArr) {
LocaleInfo localeInfo = LocaleInfo.createWithString(locale);
2021-07-15 16:24:57 +02:00
if (localeInfo == null) {
continue;
}
2019-01-23 18:03:33 +01:00
localeInfo.shortName = localeInfo.shortName.replace("-", "_");
2021-09-20 00:10:42 +02:00
unofficialLanguages.add(localeInfo);
}
}
}
private HashMap<String, String> getLocaleFileStrings(File file) {
2017-07-08 18:32:04 +02:00
return getLocaleFileStrings(file, false);
}
private HashMap<String, String> getLocaleFileStrings(File file, boolean preserveEscapes) {
2015-02-27 20:57:58 +01:00
FileInputStream stream = null;
2017-07-08 18:32:04 +02:00
reloadLastFile = false;
try {
2017-07-08 18:32:04 +02:00
if (!file.exists()) {
return new HashMap<>();
}
2015-02-01 19:51:02 +01:00
HashMap<String, String> stringMap = new HashMap<>();
XmlPullParser parser = Xml.newPullParser();
2018-07-30 04:07:02 +02:00
//AndroidUtilities.copyFile(file, new File(ApplicationLoader.applicationContext.getExternalFilesDir(null), "locale10.xml"));
2015-02-27 20:57:58 +01:00
stream = new FileInputStream(file);
parser.setInput(stream, "UTF-8");
int eventType = parser.getEventType();
String name = null;
String value = null;
String attrName = null;
while (eventType != XmlPullParser.END_DOCUMENT) {
2017-07-08 18:32:04 +02:00
if (eventType == XmlPullParser.START_TAG) {
name = parser.getName();
int c = parser.getAttributeCount();
if (c > 0) {
attrName = parser.getAttributeValue(0);
}
2017-07-08 18:32:04 +02:00
} else if (eventType == XmlPullParser.TEXT) {
if (attrName != null) {
value = parser.getText();
2014-04-03 12:23:39 +02:00
if (value != null) {
value = value.trim();
2017-07-08 18:32:04 +02:00
if (preserveEscapes) {
value = value.replace("<", "&lt;").replace(">", "&gt;").replace("'", "\\'").replace("& ", "&amp; ");
} else {
value = value.replace("\\n", "\n");
value = value.replace("\\", "");
String old = value;
value = value.replace("&lt;", "<");
if (!reloadLastFile && !value.equals(old)) {
reloadLastFile = true;
}
}
2014-04-03 12:23:39 +02:00
}
}
} else if (eventType == XmlPullParser.END_TAG) {
value = null;
attrName = null;
name = null;
}
2014-04-03 12:23:39 +02:00
if (name != null && name.equals("string") && value != null && attrName != null && value.length() != 0 && attrName.length() != 0) {
stringMap.put(attrName, value);
name = null;
value = null;
attrName = null;
}
eventType = parser.next();
}
return stringMap;
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2017-07-08 18:32:04 +02:00
reloadLastFile = true;
2015-02-27 20:57:58 +01:00
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2015-02-27 20:57:58 +01:00
}
}
2015-12-09 19:27:52 +01:00
return new HashMap<>();
}
2018-07-30 04:07:02 +02:00
public void applyLanguage(LocaleInfo localeInfo, boolean override, boolean init, final int currentAccount) {
applyLanguage(localeInfo, override, init, false, false, currentAccount);
}
2018-07-30 04:07:02 +02:00
public void applyLanguage(final LocaleInfo localeInfo, boolean override, boolean init, boolean fromFile, boolean force, final int currentAccount) {
2014-03-25 11:58:47 +01:00
if (localeInfo == null) {
2014-03-25 01:25:32 +01:00
return;
}
2021-04-01 04:06:54 +02:00
2019-01-23 18:03:33 +01:00
boolean hasBase = localeInfo.hasBaseLang();
2017-07-08 18:32:04 +02:00
File pathToFile = localeInfo.getPathToFile();
2019-01-23 18:03:33 +01:00
File pathToBaseFile = localeInfo.getPathToBaseFile();
2017-07-08 18:32:04 +02:00
String shortName = localeInfo.shortName;
2017-12-08 18:35:59 +01:00
if (!init) {
2019-01-23 18:03:33 +01:00
ConnectionsManager.setLangCode(localeInfo.getLangCode());
}
LocaleInfo existingInfo = getLanguageFromDict(localeInfo.getKey());
if (existingInfo == null) {
if (localeInfo.isRemote()) {
remoteLanguages.add(localeInfo);
remoteLanguagesDict.put(localeInfo.getKey(), localeInfo);
languages.add(localeInfo);
languagesDict.put(localeInfo.getKey(), localeInfo);
saveOtherLanguages();
} else if (localeInfo.isUnofficial()) {
unofficialLanguages.add(localeInfo);
languagesDict.put(localeInfo.getKey(), localeInfo);
saveOtherLanguages();
}
2017-12-08 18:35:59 +01:00
}
2020-06-25 17:28:24 +02:00
loadPrebuiltLocaleFile(localeInfo);
2019-01-23 18:03:33 +01:00
if ((localeInfo.isRemote() || localeInfo.isUnofficial()) && (force || !pathToFile.exists() || hasBase && !pathToBaseFile.exists())) {
2018-07-30 04:07:02 +02:00
if (BuildVars.LOGS_ENABLED) {
2019-01-23 18:03:33 +01:00
FileLog.d("reload locale because one of file doesn't exist" + pathToFile + " " + pathToBaseFile);
2018-07-30 04:07:02 +02:00
}
2017-12-08 18:35:59 +01:00
if (init) {
2019-01-23 18:03:33 +01:00
AndroidUtilities.runOnUIThread(() -> applyRemoteLanguage(localeInfo, null, true, currentAccount));
2017-12-08 18:35:59 +01:00
} else {
2019-01-23 18:03:33 +01:00
applyRemoteLanguage(localeInfo, null, true, currentAccount);
2017-12-08 18:35:59 +01:00
}
2017-07-08 18:32:04 +02:00
}
2014-03-25 01:25:32 +01:00
try {
2015-05-21 23:27:27 +02:00
Locale newLocale;
2019-01-23 18:03:33 +01:00
String[] args;
if (!TextUtils.isEmpty(localeInfo.pluralLangCode)) {
args = localeInfo.pluralLangCode.split("_");
} else if (!TextUtils.isEmpty(localeInfo.baseLangCode)) {
args = localeInfo.baseLangCode.split("_");
} else {
args = localeInfo.shortName.split("_");
}
2017-07-08 18:32:04 +02:00
if (args.length == 1) {
2019-01-23 18:03:33 +01:00
newLocale = new Locale(args[0]);
2014-03-25 01:25:32 +01:00
} else {
2017-07-08 18:32:04 +02:00
newLocale = new Locale(args[0], args[1]);
}
if (override) {
languageOverride = localeInfo.shortName;
2018-07-30 04:07:02 +02:00
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
2014-03-25 01:25:32 +01:00
SharedPreferences.Editor editor = preferences.edit();
2017-07-08 18:32:04 +02:00
editor.putString("language", localeInfo.getKey());
2020-06-25 17:28:24 +02:00
editor.apply();
2014-03-25 01:25:32 +01:00
}
2017-07-08 18:32:04 +02:00
if (pathToFile == null) {
localeValues.clear();
} else if (!fromFile) {
2019-01-23 18:03:33 +01:00
localeValues = getLocaleFileStrings(hasBase ? localeInfo.getPathToBaseFile() : localeInfo.getPathToFile());
if (hasBase) {
localeValues.putAll(getLocaleFileStrings(localeInfo.getPathToFile()));
}
2017-07-08 18:32:04 +02:00
}
currentLocale = newLocale;
currentLocaleInfo = localeInfo;
2019-01-23 18:03:33 +01:00
2020-10-30 11:26:29 +01:00
if (!TextUtils.isEmpty(currentLocaleInfo.pluralLangCode)) {
2019-01-23 18:03:33 +01:00
currentPluralRules = allRules.get(currentLocaleInfo.pluralLangCode);
2017-12-08 18:35:59 +01:00
}
if (currentPluralRules == null) {
2019-01-23 18:03:33 +01:00
currentPluralRules = allRules.get(args[0]);
if (currentPluralRules == null) {
currentPluralRules = allRules.get(currentLocale.getLanguage());
if (currentPluralRules == null) {
currentPluralRules = new PluralRules_None();
}
}
2017-07-08 18:32:04 +02:00
}
changingConfiguration = true;
Locale.setDefault(currentLocale);
android.content.res.Configuration config = new android.content.res.Configuration();
config.locale = currentLocale;
ApplicationLoader.applicationContext.getResources().updateConfiguration(config, ApplicationLoader.applicationContext.getResources().getDisplayMetrics());
changingConfiguration = false;
if (reloadLastFile) {
2017-12-08 18:35:59 +01:00
if (init) {
2020-03-30 14:00:09 +02:00
AndroidUtilities.runOnUIThread(() -> reloadCurrentRemoteLocale(currentAccount, null, force));
2017-12-08 18:35:59 +01:00
} else {
2020-03-30 14:00:09 +02:00
reloadCurrentRemoteLocale(currentAccount, null, force);
2017-12-08 18:35:59 +01:00
}
2017-07-08 18:32:04 +02:00
reloadLastFile = false;
2014-03-25 01:25:32 +01:00
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2014-03-25 01:25:32 +01:00
changingConfiguration = false;
}
recreateFormatters();
}
2017-07-08 18:32:04 +02:00
public LocaleInfo getCurrentLocaleInfo() {
return currentLocaleInfo;
}
2020-09-30 15:48:47 +02:00
public Locale getCurrentLocale() {
return currentLocale;
}
2014-03-25 01:25:32 +01:00
public static String getCurrentLanguageName() {
2019-01-23 18:03:33 +01:00
LocaleInfo localeInfo = getInstance().currentLocaleInfo;
return localeInfo == null || TextUtils.isEmpty(localeInfo.name) ? getString("LanguageName", R.string.LanguageName) : localeInfo.name;
2014-03-25 01:25:32 +01:00
}
2014-10-04 17:56:09 +02:00
private String getStringInternal(String key, int res) {
2020-10-30 11:26:29 +01:00
return getStringInternal(key, null, res);
}
private String getStringInternal(String key, String fallback, int res) {
2019-01-23 18:03:33 +01:00
String value = BuildVars.USE_CLOUD_STRINGS ? localeValues.get(key) : null;
if (value == null) {
2020-10-30 11:26:29 +01:00
if (BuildVars.USE_CLOUD_STRINGS && fallback != null) {
value = localeValues.get(fallback);
}
if (value == null) {
try {
value = ApplicationLoader.applicationContext.getString(res);
} catch (Exception e) {
FileLog.e(e);
}
2016-04-22 15:49:00 +02:00
}
}
2021-11-17 16:02:31 +01:00
if (value == null || "".equals(value)) {
value = "LOC_ERR:" + key;
2021-11-17 16:02:31 +01:00
if (getFallbackResources() != null)
value = getFallbackResources().getString(res);
2021-01-31 18:28:28 +01:00
} else {
value = LocFiltersKt.filter(value);
}
return value;
}
2021-11-17 16:02:31 +01:00
private static Resources fallbackResources = null;
private static Resources getFallbackResources() {
if (fallbackResources == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Configuration conf = ApplicationLoader.applicationContext.getResources().getConfiguration();
conf = new Configuration(conf);
conf.setLocale(new Locale("en"));
Context localizedContext = ApplicationLoader.applicationContext.createConfigurationContext(conf);
fallbackResources = localizedContext.getResources();
}
return fallbackResources;
}
2018-08-27 10:33:11 +02:00
public static String getServerString(String key) {
String value = getInstance().localeValues.get(key);
if (value == null) {
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(key, "string", ApplicationLoader.applicationContext.getPackageName());
if (resourceId != 0) {
value = ApplicationLoader.applicationContext.getString(resourceId);
}
}
return value;
}
2014-10-04 17:56:09 +02:00
public static String getString(String key, int res) {
return getInstance().getStringInternal(key, res);
}
2020-10-30 11:26:29 +01:00
public static String getString(String key, String fallback, int res) {
return getInstance().getStringInternal(key, fallback, res);
}
2020-04-30 21:07:00 +02:00
public static String getString(String key) {
if (TextUtils.isEmpty(key)) {
return "LOC_ERR:" + key;
}
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(key, "string", ApplicationLoader.applicationContext.getPackageName());
if (resourceId != 0) {
return getString(key, resourceId);
}
return getServerString(key);
}
2017-12-08 18:35:59 +01:00
public static String getPluralString(String key, int plural) {
if (key == null || key.length() == 0 || getInstance().currentPluralRules == null) {
return "LOC_ERR:" + key;
}
String param = getInstance().stringForQuantity(getInstance().currentPluralRules.quantityForNumber(plural));
param = key + "_" + param;
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(param, "string", ApplicationLoader.applicationContext.getPackageName());
2020-10-30 11:26:29 +01:00
return getString(param, key + "_other", resourceId);
2017-12-08 18:35:59 +01:00
}
2014-07-03 16:55:04 +02:00
public static String formatPluralString(String key, int plural) {
if (key == null || key.length() == 0 || getInstance().currentPluralRules == null) {
return "LOC_ERR:" + key;
}
String param = getInstance().stringForQuantity(getInstance().currentPluralRules.quantityForNumber(plural));
param = key + "_" + param;
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(param, "string", ApplicationLoader.applicationContext.getPackageName());
2020-10-30 11:26:29 +01:00
return formatString(param, key + "_other", resourceId, plural);
2014-07-03 16:55:04 +02:00
}
2019-12-31 14:08:08 +01:00
public static String formatPluralStringComma(String key, int plural) {
try {
if (key == null || key.length() == 0 || getInstance().currentPluralRules == null) {
return "LOC_ERR:" + key;
}
String param = getInstance().stringForQuantity(getInstance().currentPluralRules.quantityForNumber(plural));
param = key + "_" + param;
StringBuilder stringBuilder = new StringBuilder(String.format(Locale.US, "%d", plural));
for (int a = stringBuilder.length() - 3; a > 0; a -= 3) {
stringBuilder.insert(a, ',');
}
String value = BuildVars.USE_CLOUD_STRINGS ? getInstance().localeValues.get(param) : null;
2020-10-30 11:26:29 +01:00
if (value == null) {
value = BuildVars.USE_CLOUD_STRINGS ? getInstance().localeValues.get(key + "_other") : null;
}
2019-12-31 14:08:08 +01:00
if (value == null) {
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(param, "string", ApplicationLoader.applicationContext.getPackageName());
value = ApplicationLoader.applicationContext.getString(resourceId);
}
value = value.replace("%1$d", "%1$s");
if (getInstance().currentLocale != null) {
return String.format(getInstance().currentLocale, value, stringBuilder);
} else {
return String.format(value, stringBuilder);
}
} catch (Exception e) {
FileLog.e(e);
return "LOC_ERR: " + key;
}
}
public static String formatString(String key, int res, Object... args) {
2020-10-30 11:26:29 +01:00
return formatString(key, null, res, args);
}
public static String formatString(String key, String fallback, int res, Object... args) {
try {
2019-01-23 18:03:33 +01:00
String value = BuildVars.USE_CLOUD_STRINGS ? getInstance().localeValues.get(key) : null;
if (value == null) {
2020-10-30 11:26:29 +01:00
if (BuildVars.USE_CLOUD_STRINGS && fallback != null) {
value = getInstance().localeValues.get(fallback);
}
if (value == null) {
value = ApplicationLoader.applicationContext.getString(res);
}
}
if (getInstance().currentLocale != null) {
return String.format(getInstance().currentLocale, value, args);
} else {
return String.format(value, args);
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
return "LOC_ERR: " + key;
}
}
2014-03-25 01:25:32 +01:00
2017-03-31 01:58:05 +02:00
public static String formatTTLString(int ttl) {
if (ttl < 60) {
return LocaleController.formatPluralString("Seconds", ttl);
} else if (ttl < 60 * 60) {
return LocaleController.formatPluralString("Minutes", ttl / 60);
} else if (ttl < 60 * 60 * 24) {
return LocaleController.formatPluralString("Hours", ttl / 60 / 60);
} else if (ttl < 60 * 60 * 24 * 7) {
return LocaleController.formatPluralString("Days", ttl / 60 / 60 / 24);
2021-07-30 16:49:55 +02:00
} else if (ttl >= 60 * 60 * 24 * 30 && ttl <= 60 * 60 * 24 * 31) {
return LocaleController.formatPluralString("Months", ttl / 60 / 60 / 24 / 30);
2017-03-31 01:58:05 +02:00
} else {
int days = ttl / 60 / 60 / 24;
if (ttl % 7 == 0) {
return LocaleController.formatPluralString("Weeks", days / 7);
} else {
return String.format("%s %s", LocaleController.formatPluralString("Weeks", days / 7), LocaleController.formatPluralString("Days", days % 7));
}
}
}
2021-04-14 03:44:46 +02:00
private static char[] defaultNumbers = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
private static char[][] otherNumbers = new char[][]{
{'٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'},
{'۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'},
{'', '१', '२', '३', '४', '५', '६', '७', '८', '९'},
{'', '૧', '૨', '૩', '૪', '૫', '૬', '૭', '૮', '૯'},
{'', '', '੨', '੩', '', '੫', '੬', '੭', '੮', '੯'},
{'', '১', '২', '৩', '', '৫', '৬', '', '৮', '৯'},
{'', '೧', '೨', '೩', '೪', '೫', '೬', '೭', '೮', '೯'},
{'', '୧', '', '୩', '୪', '୫', '୬', '୭', '୮', '୯'},
{'', '൧', '൨', '൩', '൪', '൫', '൬', '', '൮', '൯'},
{'', '௧', '௨', '௩', '௪', '௫', '௬', '௭', '௮', '௯'},
{'', '౧', '౨', '౩', '౪', '౫', '౬', '౭', '౮', '౯'},
{'', '၁', '၂', '၃', '၄', '၅', '၆', '၇', '၈', '၉'},
{'༠', '༡', '༢', '༣', '༤', '༥', '༦', '༧', '༨', '༩'},
{'᠐', '᠑', '᠒', '᠓', '᠔', '᠕', '᠖', '᠗', '᠘', '᠙'},
{'០', '១', '២', '៣', '៤', '៥', '៦', '៧', '៨', '៩'},
{'', '๑', '๒', '๓', '๔', '๕', '๖', '๗', '๘', '๙'},
{'', '໑', '໒', '໓', '໔', '໕', '໖', '໗', '໘', '໙'},
{'꧐', '꧑', '꧒', '꧓', '꧔', '꧕', '꧖', '꧗', '꧘', '꧙'}
};
public static String fixNumbers(CharSequence numbers) {
StringBuilder builder = new StringBuilder(numbers);
for (int c = 0, N = builder.length(); c < N; c++) {
char ch = builder.charAt(c);
if (ch >= '0' && ch <= '9' || ch == '.' || ch == ',') {
continue;
}
for (int a = 0; a < otherNumbers.length; a++) {
for (int b = 0; b < otherNumbers[a].length; b++) {
if (ch == otherNumbers[a][b]) {
builder.setCharAt(c, defaultNumbers[b]);
a = otherNumbers.length;
break;
}
}
}
}
return builder.toString();
}
2017-03-31 01:58:05 +02:00
public String formatCurrencyString(long amount, String type) {
2021-04-17 01:59:59 +02:00
return formatCurrencyString(amount, true, true, false, type);
2021-04-14 03:44:46 +02:00
}
2021-04-17 01:59:59 +02:00
public String formatCurrencyString(long amount, boolean fixAnything, boolean withExp, boolean editText, String type) {
2017-03-31 01:58:05 +02:00
type = type.toUpperCase();
String customFormat;
double doubleAmount;
boolean discount = amount < 0;
amount = Math.abs(amount);
2018-07-30 04:07:02 +02:00
Currency currency = Currency.getInstance(type);
2017-03-31 01:58:05 +02:00
switch (type) {
case "CLF":
customFormat = " %.4f";
doubleAmount = amount / 10000.0;
break;
2018-07-30 04:07:02 +02:00
case "IRR":
doubleAmount = amount / 100.0f;
2021-04-14 03:44:46 +02:00
if (fixAnything && amount % 100 == 0) {
2018-07-30 04:07:02 +02:00
customFormat = " %.0f";
} else {
customFormat = " %.2f";
}
break;
2017-03-31 01:58:05 +02:00
case "BHD":
case "IQD":
case "JOD":
case "KWD":
case "LYD":
case "OMR":
case "TND":
customFormat = " %.3f";
doubleAmount = amount / 1000.0;
break;
case "BIF":
case "BYR":
case "CLP":
case "CVE":
case "DJF":
case "GNF":
case "ISK":
case "JPY":
case "KMF":
case "KRW":
case "MGA":
case "PYG":
case "RWF":
case "UGX":
case "UYI":
case "VND":
case "VUV":
case "XAF":
case "XOF":
case "XPF":
customFormat = " %.0f";
doubleAmount = amount;
break;
case "MRO":
customFormat = " %.1f";
doubleAmount = amount / 10.0;
break;
default:
customFormat = " %.2f";
doubleAmount = amount / 100.0;
break;
}
2021-04-17 01:59:59 +02:00
if (!withExp) {
customFormat = " %.0f";
}
2018-07-30 04:07:02 +02:00
if (currency != null) {
2017-03-31 01:58:05 +02:00
NumberFormat format = NumberFormat.getCurrencyInstance(currentLocale != null ? currentLocale : systemDefaultLocale);
2018-07-30 04:07:02 +02:00
format.setCurrency(currency);
2021-04-17 01:59:59 +02:00
if (editText) {
format.setGroupingUsed(false);
}
if (!withExp || fixAnything && type.equals("IRR")) {
2018-07-30 04:07:02 +02:00
format.setMaximumFractionDigits(0);
}
2021-04-17 01:59:59 +02:00
String result = (discount ? "-" : "") + format.format(doubleAmount);
int idx = result.indexOf(type);
2021-04-17 16:25:35 +02:00
if (idx >= 0) {
idx += type.length();
2021-06-25 02:43:10 +02:00
if (idx < result.length() && result.charAt(idx) != ' ') {
result = result.substring(0, idx) + " " + result.substring(idx);
2021-04-17 16:25:35 +02:00
}
2021-04-17 01:59:59 +02:00
}
return result;
2017-03-31 01:58:05 +02:00
}
2017-12-08 18:35:59 +01:00
return (discount ? "-" : "") + String.format(Locale.US, type + customFormat, doubleAmount);
2017-03-31 01:58:05 +02:00
}
2021-04-14 03:44:46 +02:00
public static int getCurrencyExpDivider(String type) {
switch (type) {
case "CLF":
return 10000;
case "BHD":
case "IQD":
case "JOD":
case "KWD":
case "LYD":
case "OMR":
case "TND":
return 1000;
case "BIF":
case "BYR":
case "CLP":
case "CVE":
case "DJF":
case "GNF":
case "ISK":
case "JPY":
case "KMF":
case "KRW":
case "MGA":
case "PYG":
case "RWF":
case "UGX":
case "UYI":
case "VND":
case "VUV":
case "XAF":
case "XOF":
case "XPF":
return 1;
case "MRO":
return 10;
default:
return 100;
}
}
2017-07-08 18:32:04 +02:00
public String formatCurrencyDecimalString(long amount, String type, boolean inludeType) {
2017-03-31 01:58:05 +02:00
type = type.toUpperCase();
String customFormat;
double doubleAmount;
amount = Math.abs(amount);
switch (type) {
case "CLF":
customFormat = " %.4f";
doubleAmount = amount / 10000.0;
break;
2018-07-30 04:07:02 +02:00
case "IRR":
doubleAmount = amount / 100.0f;
if (amount % 100 == 0) {
customFormat = " %.0f";
} else {
customFormat = " %.2f";
}
break;
2017-03-31 01:58:05 +02:00
case "BHD":
case "IQD":
case "JOD":
case "KWD":
case "LYD":
case "OMR":
case "TND":
customFormat = " %.3f";
doubleAmount = amount / 1000.0;
break;
case "BIF":
case "BYR":
case "CLP":
case "CVE":
case "DJF":
case "GNF":
case "ISK":
case "JPY":
case "KMF":
case "KRW":
case "MGA":
case "PYG":
case "RWF":
case "UGX":
case "UYI":
case "VND":
case "VUV":
case "XAF":
case "XOF":
case "XPF":
customFormat = " %.0f";
doubleAmount = amount;
break;
case "MRO":
customFormat = " %.1f";
doubleAmount = amount / 10.0;
break;
default:
customFormat = " %.2f";
doubleAmount = amount / 100.0;
break;
}
2017-12-08 18:35:59 +01:00
return String.format(Locale.US, inludeType ? type : "" + customFormat, doubleAmount).trim();
2017-03-31 01:58:05 +02:00
}
public static String formatStringSimple(String string, Object... args) {
try {
if (getInstance().currentLocale != null) {
return String.format(getInstance().currentLocale, string, args);
} else {
return String.format(string, args);
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
return "LOC_ERR: " + string;
}
}
2020-07-26 10:03:38 +02:00
public static String formatDuration(int duration) {
if (duration <= 0) {
return formatPluralString("Seconds", 0);
}
final int hours = duration / 3600;
final int minutes = duration / 60 % 60;
final int seconds = duration % 60;
final StringBuilder stringBuilder = new StringBuilder();
if (hours > 0) {
stringBuilder.append(formatPluralString("Hours", hours));
}
if (minutes > 0) {
if (stringBuilder.length() > 0) {
stringBuilder.append(' ');
}
stringBuilder.append(formatPluralString("Minutes", minutes));
}
if (seconds > 0) {
if (stringBuilder.length() > 0) {
stringBuilder.append(' ');
}
stringBuilder.append(formatPluralString("Seconds", seconds));
}
return stringBuilder.toString();
}
2017-03-31 01:58:05 +02:00
public static String formatCallDuration(int duration) {
if (duration > 3600) {
String result = LocaleController.formatPluralString("Hours", duration / 3600);
int minutes = duration % 3600 / 60;
if (minutes > 0) {
result += ", " + LocaleController.formatPluralString("Minutes", minutes);
}
return result;
} else if (duration > 60) {
return LocaleController.formatPluralString("Minutes", duration / 60);
} else {
return LocaleController.formatPluralString("Seconds", duration);
}
}
2014-03-25 01:25:32 +01:00
public void onDeviceConfigurationChange(Configuration newConfig) {
if (changingConfiguration) {
return;
}
is24HourFormat = DateFormat.is24HourFormat(ApplicationLoader.applicationContext);
2014-03-25 01:25:32 +01:00
systemDefaultLocale = newConfig.locale;
if (languageOverride != null) {
LocaleInfo toSet = currentLocaleInfo;
currentLocaleInfo = null;
2019-06-17 05:54:01 +02:00
applyLanguage(toSet, false, true, UserConfig.selectedAccount);
2014-03-25 01:25:32 +01:00
} else {
Locale newLocale = newConfig.locale;
if (newLocale != null) {
String d1 = newLocale.getDisplayName();
String d2 = currentLocale.getDisplayName();
if (d1 != null && d2 != null && !d1.equals(d2)) {
recreateFormatters();
}
currentLocale = newLocale;
2019-01-23 18:03:33 +01:00
if (currentLocaleInfo != null && !TextUtils.isEmpty(currentLocaleInfo.pluralLangCode)) {
currentPluralRules = allRules.get(currentLocaleInfo.pluralLangCode);
}
if (currentPluralRules == null) {
2019-01-23 18:03:33 +01:00
currentPluralRules = allRules.get(currentLocale.getLanguage());
if (currentPluralRules == null) {
currentPluralRules = allRules.get("en");
}
}
2014-03-25 01:25:32 +01:00
}
}
2019-01-23 18:03:33 +01:00
String newSystemLocale = getSystemLocaleStringIso639();
if (currentSystemLocale != null && !newSystemLocale.equals(currentSystemLocale)) {
currentSystemLocale = newSystemLocale;
ConnectionsManager.setSystemLangCode(currentSystemLocale);
}
2014-03-25 01:25:32 +01:00
}
public static String formatDateChat(long date) {
2019-09-10 12:56:11 +02:00
return formatDateChat(date, false);
}
public static String formatDateChat(long date, boolean checkYear) {
2021-03-15 11:47:03 +01:00
if (getInstance().chatDate == null) {
getInstance().recreateFormatters();
}
2016-03-16 13:26:32 +01:00
try {
2020-12-17 06:45:19 +01:00
Calendar calendar = Calendar.getInstance();
2019-09-10 12:56:11 +02:00
calendar.setTimeInMillis(System.currentTimeMillis());
int currentYear = calendar.get(Calendar.YEAR);
2017-03-31 01:58:05 +02:00
date *= 1000;
2014-03-25 01:25:32 +01:00
2019-09-10 12:56:11 +02:00
calendar.setTimeInMillis(date);
2021-04-01 02:48:10 +02:00
PersianCalendar persianCalendar = null;
2021-04-01 04:06:54 +02:00
if (usePersianCalendar) {
2021-04-01 02:48:10 +02:00
persianCalendar = new PersianCalendar(date);
}
2019-09-10 12:56:11 +02:00
if (checkYear && currentYear == calendar.get(Calendar.YEAR) || !checkYear && Math.abs(System.currentTimeMillis() - date) < 31536000000L) {
2021-04-01 04:06:54 +02:00
if (usePersianCalendar) {
2021-04-01 02:48:10 +02:00
return persianCalendar.getPersianMonthDay();
} else {
return getInstance().chatDate.format(date);
}
} else {
2021-04-01 04:06:54 +02:00
if (usePersianCalendar) {
2021-04-03 03:21:46 +02:00
return persianCalendar.getPersianNormalDate();
2021-04-01 02:48:10 +02:00
} else {
return getInstance().chatFullDate.format(date);
}
2016-03-16 13:26:32 +01:00
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2014-03-25 01:25:32 +01:00
}
2016-03-16 13:26:32 +01:00
return "LOC_ERR: formatDateChat";
2014-03-25 01:25:32 +01:00
}
public static String formatDate(long date) {
2015-05-21 23:27:27 +02:00
try {
2017-03-31 01:58:05 +02:00
date *= 1000;
2020-12-17 06:45:19 +01:00
Calendar rightNow = Calendar.getInstance();
2015-05-21 23:27:27 +02:00
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
2017-03-31 01:58:05 +02:00
rightNow.setTimeInMillis(date);
2015-05-21 23:27:27 +02:00
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
if (dateDay == day && year == dateYear) {
2017-03-31 01:58:05 +02:00
return getInstance().formatterDay.format(new Date(date));
2015-05-21 23:27:27 +02:00
} else if (dateDay + 1 == day && year == dateYear) {
return getString("Yesterday", R.string.Yesterday);
2017-03-31 01:58:05 +02:00
} else if (Math.abs(System.currentTimeMillis() - date) < 31536000000L) {
2019-01-23 18:03:33 +01:00
return getInstance().formatterDayMonth.format(new Date(date));
2015-05-21 23:27:27 +02:00
} else {
2017-03-31 01:58:05 +02:00
return getInstance().formatterYear.format(new Date(date));
2015-05-21 23:27:27 +02:00
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2014-03-25 01:25:32 +01:00
}
2016-03-16 13:26:32 +01:00
return "LOC_ERR: formatDate";
2014-03-25 01:25:32 +01:00
}
2020-03-30 14:00:09 +02:00
public static String formatDateAudio(long date, boolean shortFormat) {
2016-03-06 02:49:31 +01:00
try {
2017-03-31 01:58:05 +02:00
date *= 1000;
2020-12-17 06:45:19 +01:00
Calendar rightNow = Calendar.getInstance();
2017-03-31 01:58:05 +02:00
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
if (dateDay == day && year == dateYear) {
2020-03-30 14:00:09 +02:00
if (shortFormat) {
return LocaleController.formatString("TodayAtFormatted", R.string.TodayAtFormatted, getInstance().formatterDay.format(new Date(date)));
} else {
return LocaleController.formatString("TodayAtFormattedWithToday", R.string.TodayAtFormattedWithToday, getInstance().formatterDay.format(new Date(date)));
}
2017-03-31 01:58:05 +02:00
} else if (dateDay + 1 == day && year == dateYear) {
2018-07-30 04:07:02 +02:00
return LocaleController.formatString("YesterdayAtFormatted", R.string.YesterdayAtFormatted, getInstance().formatterDay.format(new Date(date)));
2017-03-31 01:58:05 +02:00
} else if (Math.abs(System.currentTimeMillis() - date) < 31536000000L) {
2019-01-23 18:03:33 +01:00
return LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterDayMonth.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
2017-03-31 01:58:05 +02:00
} else {
return LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterYear.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
}
} catch (Exception e) {
FileLog.e(e);
}
return "LOC_ERR";
}
public static String formatDateCallLog(long date) {
try {
date *= 1000;
2020-12-17 06:45:19 +01:00
Calendar rightNow = Calendar.getInstance();
2016-03-06 02:49:31 +01:00
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
2017-03-31 01:58:05 +02:00
rightNow.setTimeInMillis(date);
2016-03-06 02:49:31 +01:00
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
2021-04-01 02:48:10 +02:00
PersianCalendar persianCalendar = null;
2021-04-01 04:06:54 +02:00
if (usePersianCalendar) {
2021-04-01 02:48:10 +02:00
persianCalendar = new PersianCalendar(date);
}
2016-03-06 02:49:31 +01:00
if (dateDay == day && year == dateYear) {
2017-03-31 01:58:05 +02:00
return getInstance().formatterDay.format(new Date(date));
2016-03-06 02:49:31 +01:00
} else if (dateDay + 1 == day && year == dateYear) {
2018-07-30 04:07:02 +02:00
return LocaleController.formatString("YesterdayAtFormatted", R.string.YesterdayAtFormatted, getInstance().formatterDay.format(new Date(date)));
2017-03-31 01:58:05 +02:00
} else if (Math.abs(System.currentTimeMillis() - date) < 31536000000L) {
2021-04-01 04:06:54 +02:00
if (usePersianCalendar) {
2021-04-01 02:48:10 +02:00
return LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, persianCalendar.getPersianMonthDay(), getInstance().formatterDay.format(new Date(date)));
} else {
return LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().chatDate.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
}
2016-03-06 02:49:31 +01:00
} else {
2021-04-01 04:06:54 +02:00
if (usePersianCalendar) {
2021-04-01 02:48:10 +02:00
return LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, persianCalendar.getPersianNormalDate(), getInstance().formatterDay.format(new Date(date)));
} else {
return LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().chatFullDate.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
}
2016-03-06 02:49:31 +01:00
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2016-03-06 02:49:31 +01:00
}
return "LOC_ERR";
}
2017-12-08 18:35:59 +01:00
public static String formatLocationUpdateDate(long date) {
try {
date *= 1000;
2020-12-17 06:45:19 +01:00
Calendar rightNow = Calendar.getInstance();
2017-12-08 18:35:59 +01:00
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
if (dateDay == day && year == dateYear) {
2018-07-30 04:07:02 +02:00
int diff = (int) (ConnectionsManager.getInstance(UserConfig.selectedAccount).getCurrentTime() - date / 1000) / 60;
2017-12-08 18:35:59 +01:00
if (diff < 1) {
return LocaleController.getString("LocationUpdatedJustNow", R.string.LocationUpdatedJustNow);
} else if (diff < 60) {
return LocaleController.formatPluralString("UpdatedMinutes", diff);
}
2018-07-30 04:07:02 +02:00
return LocaleController.formatString("LocationUpdatedFormatted", R.string.LocationUpdatedFormatted, LocaleController.formatString("TodayAtFormatted", R.string.TodayAtFormatted, getInstance().formatterDay.format(new Date(date))));
2017-12-08 18:35:59 +01:00
} else if (dateDay + 1 == day && year == dateYear) {
2018-07-30 04:07:02 +02:00
return LocaleController.formatString("LocationUpdatedFormatted", R.string.LocationUpdatedFormatted, LocaleController.formatString("YesterdayAtFormatted", R.string.YesterdayAtFormatted, getInstance().formatterDay.format(new Date(date))));
2017-12-08 18:35:59 +01:00
} else if (Math.abs(System.currentTimeMillis() - date) < 31536000000L) {
2019-01-23 18:03:33 +01:00
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterDayMonth.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
2018-07-30 04:07:02 +02:00
return LocaleController.formatString("LocationUpdatedFormatted", R.string.LocationUpdatedFormatted, format);
2017-12-08 18:35:59 +01:00
} else {
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterYear.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
2018-07-30 04:07:02 +02:00
return LocaleController.formatString("LocationUpdatedFormatted", R.string.LocationUpdatedFormatted, format);
2017-12-08 18:35:59 +01:00
}
} catch (Exception e) {
FileLog.e(e);
}
return "LOC_ERR";
}
public static String formatLocationLeftTime(int time) {
String text;
int hours = time / 60 / 60;
time -= hours * 60 * 60;
int minutes = time / 60;
time -= minutes * 60;
if (hours != 0) {
text = String.format("%dh", hours + (minutes > 30 ? 1 : 0));
} else if (minutes != 0) {
text = String.format("%d", minutes + (time > 30 ? 1 : 0));
} else {
text = String.format("%d", time);
}
return text;
}
2014-03-25 01:25:32 +01:00
public static String formatDateOnline(long date) {
2015-05-21 23:27:27 +02:00
try {
2017-03-31 01:58:05 +02:00
date *= 1000;
2020-12-17 06:45:19 +01:00
Calendar rightNow = Calendar.getInstance();
2015-05-21 23:27:27 +02:00
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
2017-03-31 01:58:05 +02:00
rightNow.setTimeInMillis(date);
2015-05-21 23:27:27 +02:00
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
2021-04-01 02:48:10 +02:00
PersianCalendar persianCalendar = null;
2021-04-01 04:06:54 +02:00
if (usePersianCalendar) {
2021-04-01 02:48:10 +02:00
persianCalendar = new PersianCalendar(date);
}
2015-05-21 23:27:27 +02:00
if (dateDay == day && year == dateYear) {
2018-07-30 04:07:02 +02:00
return LocaleController.formatString("LastSeenFormatted", R.string.LastSeenFormatted, LocaleController.formatString("TodayAtFormatted", R.string.TodayAtFormatted, getInstance().formatterDay.format(new Date(date))));
2015-10-29 18:10:07 +01:00
/*int diff = (int) (ConnectionsManager.getInstance().getCurrentTime() - date) / 60;
if (diff < 1) {
return LocaleController.getString("LastSeenNow", R.string.LastSeenNow);
} else if (diff < 60) {
return LocaleController.formatPluralString("LastSeenMinutes", diff);
} else {
return LocaleController.formatPluralString("LastSeenHours", (int) Math.ceil(diff / 60.0f));
}*/
2015-05-21 23:27:27 +02:00
} else if (dateDay + 1 == day && year == dateYear) {
2018-07-30 04:07:02 +02:00
return LocaleController.formatString("LastSeenFormatted", R.string.LastSeenFormatted, LocaleController.formatString("YesterdayAtFormatted", R.string.YesterdayAtFormatted, getInstance().formatterDay.format(new Date(date))));
2017-03-31 01:58:05 +02:00
} else if (Math.abs(System.currentTimeMillis() - date) < 31536000000L) {
2021-04-01 04:06:54 +02:00
if (usePersianCalendar) {
2021-04-01 02:48:10 +02:00
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, persianCalendar.getPersianMonthDay(), getInstance().formatterDay.format(new Date(date)));
return LocaleController.formatString("LastSeenDateFormatted", R.string.LastSeenDateFormatted, format);
} else {
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterDayMonth.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
return LocaleController.formatString("LastSeenDateFormatted", R.string.LastSeenDateFormatted, format);
}
2015-05-21 23:27:27 +02:00
} else {
2021-04-01 04:06:54 +02:00
if (usePersianCalendar) {
2021-04-01 02:48:10 +02:00
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, persianCalendar.getPersianNormalDate(), getInstance().formatterDay.format(new Date(date)));
return LocaleController.formatString("LastSeenDateFormatted", R.string.LastSeenDateFormatted, format);
} else {
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterYear.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
return LocaleController.formatString("LastSeenDateFormatted", R.string.LastSeenDateFormatted, format);
}
2015-05-21 23:27:27 +02:00
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2014-03-25 01:25:32 +01:00
}
2015-05-21 23:27:27 +02:00
return "LOC_ERR";
2014-03-25 01:25:32 +01:00
}
private FastDateFormat createFormatter(Locale locale, String format, String defaultFormat) {
if (format == null || format.length() == 0) {
format = defaultFormat;
}
2015-05-21 23:27:27 +02:00
FastDateFormat formatter;
try {
formatter = FastDateFormat.getInstance(format, locale);
} catch (Exception e) {
format = defaultFormat;
formatter = FastDateFormat.getInstance(format, locale);
}
return formatter;
}
2014-10-04 17:56:09 +02:00
public void recreateFormatters() {
2014-10-07 22:14:27 +02:00
Locale locale = currentLocale;
if (locale == null) {
locale = Locale.getDefault();
}
2014-03-25 01:25:32 +01:00
String lang = locale.getLanguage();
if (lang == null) {
lang = "en";
}
2017-12-08 18:35:59 +01:00
lang = lang.toLowerCase();
2019-01-23 18:03:33 +01:00
isRTL = lang.length() == 2 && (lang.equals("ar") || lang.equals("fa") || lang.equals("he") || lang.equals("iw")) ||
lang.startsWith("ar_") || lang.startsWith("fa_") || lang.startsWith("he_") || lang.startsWith("iw_")
|| currentLocaleInfo != null && currentLocaleInfo.isRtl;
2014-03-25 01:25:32 +01:00
2020-09-30 15:48:47 +02:00
formatterMonthYear = createFormatter(locale, getStringInternal("formatterMonthYear", R.string.formatterMonthYear), "MMM yyyy");
2019-01-23 18:03:33 +01:00
formatterDayMonth = createFormatter(locale, getStringInternal("formatterMonth", R.string.formatterMonth), "dd MMM");
formatterYear = createFormatter(locale, getStringInternal("formatterYear", R.string.formatterYear), "dd.MM.yy");
formatterYearMax = createFormatter(locale, getStringInternal("formatterYearMax", R.string.formatterYearMax), "dd.MM.yyyy");
chatDate = createFormatter(locale, getStringInternal("chatDate", R.string.chatDate), "d MMMM");
chatFullDate = createFormatter(locale, getStringInternal("chatFullDate", R.string.chatFullDate), "d MMMM yyyy");
formatterWeek = createFormatter(locale, getStringInternal("formatterWeek", R.string.formatterWeek), "EEE");
2020-09-30 15:48:47 +02:00
formatterWeekLong = createFormatter(locale, getStringInternal("formatterWeekLong", R.string.formatterWeekLong), "EEEE");
2019-09-10 12:56:11 +02:00
formatterScheduleDay = createFormatter(locale, getStringInternal("formatDateSchedule", R.string.formatDateSchedule), "MMM d");
formatterScheduleYear = createFormatter(locale, getStringInternal("formatDateScheduleYear", R.string.formatDateScheduleYear), "MMM d yyyy");
2021-11-21 16:27:45 +01:00
formatterDay = createFormatter(lang.toLowerCase().equals("ar") || lang.toLowerCase().equals("ko") ? locale : Locale.US, (is24HourFormat ? getStringInternal("formatterDay24H", R.string.formatterDay24H) : getStringInternal("formatterDay12H", R.string.formatterDay12H)).replace(":mm", NekomuraConfig.showSeconds.Bool() ? ":mm:ss" : ":mm"), (is24HourFormat ? "HH:mm" : "h:mm a").replace(":mm", NekomuraConfig.showSeconds.Bool() ? ":mm:ss" : ":mm"));
2017-03-31 01:58:05 +02:00
formatterStats = createFormatter(locale, is24HourFormat ? getStringInternal("formatterStats24H", R.string.formatterStats24H) : getStringInternal("formatterStats12H", R.string.formatterStats12H), is24HourFormat ? "MMM dd yyyy, HH:mm" : "MMM dd yyyy, h:mm a");
2017-07-08 18:32:04 +02:00
formatterBannedUntil = createFormatter(locale, is24HourFormat ? getStringInternal("formatterBannedUntil24H", R.string.formatterBannedUntil24H) : getStringInternal("formatterBannedUntil12H", R.string.formatterBannedUntil12H), is24HourFormat ? "MMM dd yyyy, HH:mm" : "MMM dd yyyy, h:mm a");
formatterBannedUntilThisYear = createFormatter(locale, is24HourFormat ? getStringInternal("formatterBannedUntilThisYear24H", R.string.formatterBannedUntilThisYear24H) : getStringInternal("formatterBannedUntilThisYear12H", R.string.formatterBannedUntilThisYear12H), is24HourFormat ? "MMM dd, HH:mm" : "MMM dd, h:mm a");
2019-09-10 12:56:11 +02:00
formatterScheduleSend[0] = createFormatter(locale, getStringInternal("SendTodayAt", R.string.SendTodayAt), "'Send today at' HH:mm");
formatterScheduleSend[1] = createFormatter(locale, getStringInternal("SendDayAt", R.string.SendDayAt), "'Send on' MMM d 'at' HH:mm");
formatterScheduleSend[2] = createFormatter(locale, getStringInternal("SendDayYearAt", R.string.SendDayYearAt), "'Send on' MMM d yyyy 'at' HH:mm");
formatterScheduleSend[3] = createFormatter(locale, getStringInternal("RemindTodayAt", R.string.RemindTodayAt), "'Remind today at' HH:mm");
formatterScheduleSend[4] = createFormatter(locale, getStringInternal("RemindDayAt", R.string.RemindDayAt), "'Remind on' MMM d 'at' HH:mm");
formatterScheduleSend[5] = createFormatter(locale, getStringInternal("RemindDayYearAt", R.string.RemindDayYearAt), "'Remind on' MMM d yyyy 'at' HH:mm");
2021-04-14 03:44:46 +02:00
formatterScheduleSend[6] = createFormatter(locale, getStringInternal("StartTodayAt", R.string.StartTodayAt), "'Start today at' HH:mm");
formatterScheduleSend[7] = createFormatter(locale, getStringInternal("StartDayAt", R.string.StartDayAt), "'Start on' MMM d 'at' HH:mm");
formatterScheduleSend[8] = createFormatter(locale, getStringInternal("StartDayYearAt", R.string.StartDayYearAt), "'Start on' MMM d yyyy 'at' HH:mm");
formatterScheduleSend[9] = createFormatter(locale, getStringInternal("StartShortTodayAt", R.string.StartShortTodayAt), "'Today,' HH:mm");
formatterScheduleSend[10] = createFormatter(locale, getStringInternal("StartShortDayAt", R.string.StartShortDayAt), "MMM d',' HH:mm");
formatterScheduleSend[11] = createFormatter(locale, getStringInternal("StartShortDayYearAt", R.string.StartShortDayYearAt), "MMM d yyyy, HH:mm");
formatterScheduleSend[12] = createFormatter(locale, getStringInternal("StartsTodayAt", R.string.StartsTodayAt), "'Starts today at' HH:mm");
formatterScheduleSend[13] = createFormatter(locale, getStringInternal("StartsDayAt", R.string.StartsDayAt), "'Starts on' MMM d 'at' HH:mm");
formatterScheduleSend[14] = createFormatter(locale, getStringInternal("StartsDayYearAt", R.string.StartsDayYearAt), "'Starts on' MMM d yyyy 'at' HH:mm");
2017-03-31 01:58:05 +02:00
}
public static boolean isRTLCharacter(char ch) {
return Character.getDirectionality(ch) == Character.DIRECTIONALITY_RIGHT_TO_LEFT || Character.getDirectionality(ch) == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC || Character.getDirectionality(ch) == Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING || Character.getDirectionality(ch) == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE;
2014-03-25 01:25:32 +01:00
}
2021-04-14 03:44:46 +02:00
public static String formatStartsTime(long date, int type) {
return formatStartsTime(date, type, true);
}
public static String formatStartsTime(long date, int type, boolean needToday) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
int currentYear = calendar.get(Calendar.YEAR);
int currentDay = calendar.get(Calendar.DAY_OF_YEAR);
calendar.setTimeInMillis(date * 1000);
int selectedYear = calendar.get(Calendar.YEAR);
int selectedDay = calendar.get(Calendar.DAY_OF_YEAR);
int num;
if (currentYear == selectedYear) {
if (needToday && selectedDay == currentDay) {
num = 0;
} else {
num = 1;
}
} else {
num = 2;
}
if (type == 1) {
num += 3;
} else if (type == 2) {
num += 6;
} else if (type == 3) {
num += 9;
} else if (type == 4) {
num += 12;
}
return LocaleController.getInstance().formatterScheduleSend[num].format(calendar.getTimeInMillis());
}
2019-01-23 18:03:33 +01:00
public static String formatSectionDate(long date) {
2021-11-05 11:06:49 +01:00
return formatYearMont(date, false);
}
public static String formatYearMont(long date, boolean alwaysShowYear) {
2019-01-23 18:03:33 +01:00
try {
date *= 1000;
2020-12-17 06:45:19 +01:00
Calendar rightNow = Calendar.getInstance();
2019-01-23 18:03:33 +01:00
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date);
int dateYear = rightNow.get(Calendar.YEAR);
2019-02-08 03:30:32 +01:00
int month = rightNow.get(Calendar.MONTH);
final String[] months = new String[]{
LocaleController.getString("January", R.string.January),
LocaleController.getString("February", R.string.February),
LocaleController.getString("March", R.string.March),
LocaleController.getString("April", R.string.April),
LocaleController.getString("May", R.string.May),
LocaleController.getString("June", R.string.June),
LocaleController.getString("July", R.string.July),
LocaleController.getString("August", R.string.August),
LocaleController.getString("September", R.string.September),
LocaleController.getString("October", R.string.October),
LocaleController.getString("November", R.string.November),
LocaleController.getString("December", R.string.December)
};
2021-11-05 11:06:49 +01:00
if (year == dateYear && !alwaysShowYear) {
2019-02-08 03:30:32 +01:00
return months[month];
2019-01-23 18:03:33 +01:00
} else {
2019-02-08 03:30:32 +01:00
return months[month] + " " + dateYear;
2019-01-23 18:03:33 +01:00
}
} catch (Exception e) {
FileLog.e(e);
}
return "LOC_ERR";
}
2017-07-08 18:32:04 +02:00
public static String formatDateForBan(long date) {
try {
date *= 1000;
2020-12-17 06:45:19 +01:00
Calendar rightNow = Calendar.getInstance();
2017-07-08 18:32:04 +02:00
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date);
int dateYear = rightNow.get(Calendar.YEAR);
if (year == dateYear) {
return getInstance().formatterBannedUntilThisYear.format(new Date(date));
} else {
return getInstance().formatterBannedUntil.format(new Date(date));
}
} catch (Exception e) {
FileLog.e(e);
}
return "LOC_ERR";
}
2014-03-25 01:25:32 +01:00
public static String stringForMessageListDate(long date) {
2015-05-21 23:27:27 +02:00
try {
2017-03-31 01:58:05 +02:00
date *= 1000;
2020-12-17 06:45:19 +01:00
Calendar rightNow = Calendar.getInstance();
2015-05-21 23:27:27 +02:00
int day = rightNow.get(Calendar.DAY_OF_YEAR);
2017-03-31 01:58:05 +02:00
rightNow.setTimeInMillis(date);
2015-05-21 23:27:27 +02:00
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
2017-03-31 01:58:05 +02:00
if (Math.abs(System.currentTimeMillis() - date) >= 31536000000L) {
return getInstance().formatterYear.format(new Date(date));
2014-03-25 01:25:32 +01:00
} else {
2015-05-21 23:27:27 +02:00
int dayDiff = dateDay - day;
2017-07-08 18:32:04 +02:00
if (dayDiff == 0 || dayDiff == -1 && System.currentTimeMillis() - date < 60 * 60 * 8 * 1000) {
2017-03-31 01:58:05 +02:00
return getInstance().formatterDay.format(new Date(date));
2017-07-08 18:32:04 +02:00
} else if (dayDiff > -7 && dayDiff <= -1) {
2017-03-31 01:58:05 +02:00
return getInstance().formatterWeek.format(new Date(date));
2021-04-01 04:06:54 +02:00
} else if (usePersianCalendar) {
2021-04-01 02:48:10 +02:00
return new PersianCalendar(date).getPersianMonthDay();
2015-05-21 23:27:27 +02:00
} else {
2019-01-23 18:03:33 +01:00
return getInstance().formatterDayMonth.format(new Date(date));
2015-05-21 23:27:27 +02:00
}
2014-03-25 01:25:32 +01:00
}
2015-05-21 23:27:27 +02:00
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2014-03-25 01:25:32 +01:00
}
2015-05-21 23:27:27 +02:00
return "LOC_ERR";
2014-03-25 01:25:32 +01:00
}
2015-09-24 22:52:02 +02:00
public static String formatShortNumber(int number, int[] rounded) {
2021-10-30 08:05:57 +02:00
if (NekomuraConfig.disableNumberRounding.Bool()) {
if (rounded != null) {
rounded[0] = number;
}
return String.valueOf(number);
}
2017-12-08 18:35:59 +01:00
StringBuilder K = new StringBuilder();
2015-09-24 22:52:02 +02:00
int lastDec = 0;
2015-12-09 19:27:52 +01:00
int KCount = 0;
2015-09-24 22:52:02 +02:00
while (number / 1000 > 0) {
2017-12-08 18:35:59 +01:00
K.append("K");
2015-09-24 22:52:02 +02:00
lastDec = (number % 1000) / 100;
number /= 1000;
}
if (rounded != null) {
double value = number + lastDec / 10.0;
for (int a = 0; a < K.length(); a++) {
value *= 1000;
}
rounded[0] = (int) value;
}
if (lastDec != 0 && K.length() > 0) {
2015-12-09 19:27:52 +01:00
if (K.length() == 2) {
return String.format(Locale.US, "%d.%dM", number, lastDec);
} else {
2017-12-08 18:35:59 +01:00
return String.format(Locale.US, "%d.%d%s", number, lastDec, K.toString());
2015-12-09 19:27:52 +01:00
}
2015-09-24 22:52:02 +02:00
}
if (K.length() == 2) {
return String.format(Locale.US, "%dM", number);
} else {
2017-12-08 18:35:59 +01:00
return String.format(Locale.US, "%d%s", number, K.toString());
}
2015-09-24 22:52:02 +02:00
}
2018-07-30 04:07:02 +02:00
public static String formatUserStatus(int currentAccount, TLRPC.User user) {
2019-06-04 12:14:50 +02:00
return formatUserStatus(currentAccount, user, null);
}
2020-07-26 10:03:38 +02:00
public static String formatJoined(long date) {
try {
date *= 1000;
String format;
if (Math.abs(System.currentTimeMillis() - date) < 31536000000L) {
format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterDayMonth.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
} else {
format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterYear.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
}
return formatString("ChannelOtherSubscriberJoined", R.string.ChannelOtherSubscriberJoined, format);
} catch (Exception e) {
FileLog.e(e);
}
return "LOC_ERR";
}
2021-01-28 15:15:51 +01:00
public static String formatImportedDate(long date) {
try {
date *= 1000;
Date dt = new Date(date);
return String.format("%1$s, %2$s", getInstance().formatterYear.format(dt), getInstance().formatterDay.format(dt));
} catch (Exception e) {
FileLog.e(e);
}
return "LOC_ERR";
}
2019-06-04 12:14:50 +02:00
public static String formatUserStatus(int currentAccount, TLRPC.User user, boolean[] isOnline) {
2014-11-19 02:23:46 +01:00
if (user != null && user.status != null && user.status.expires == 0) {
if (user.status instanceof TLRPC.TL_userStatusRecently) {
user.status.expires = -100;
} else if (user.status instanceof TLRPC.TL_userStatusLastWeek) {
user.status.expires = -101;
} else if (user.status instanceof TLRPC.TL_userStatusLastMonth) {
user.status.expires = -102;
}
}
2014-11-21 01:14:44 +01:00
if (user != null && user.status != null && user.status.expires <= 0) {
2018-07-30 04:07:02 +02:00
if (MessagesController.getInstance(currentAccount).onlinePrivacy.containsKey(user.id)) {
2019-06-04 12:14:50 +02:00
if (isOnline != null) {
isOnline[0] = true;
}
2014-11-21 01:14:44 +01:00
return getString("Online", R.string.Online);
}
}
2015-06-29 19:12:11 +02:00
if (user == null || user.status == null || user.status.expires == 0 || UserObject.isDeleted(user) || user instanceof TLRPC.TL_userEmpty) {
2014-11-17 03:44:57 +01:00
return getString("ALongTimeAgo", R.string.ALongTimeAgo);
} else {
2018-07-30 04:07:02 +02:00
int currentTime = ConnectionsManager.getInstance(currentAccount).getCurrentTime();
if (user.status.expires > currentTime) {
2019-06-04 12:14:50 +02:00
if (isOnline != null) {
isOnline[0] = true;
}
return getString("Online", R.string.Online);
} else {
if (user.status.expires == -1) {
return getString("Invisible", R.string.Invisible);
2014-11-17 03:44:57 +01:00
} else if (user.status.expires == -100) {
return getString("Lately", R.string.Lately);
} else if (user.status.expires == -101) {
return getString("WithinAWeek", R.string.WithinAWeek);
} else if (user.status.expires == -102) {
return getString("WithinAMonth", R.string.WithinAMonth);
2020-06-25 17:28:24 +02:00
} else {
return formatDateOnline(user.status.expires);
}
}
}
}
2014-07-03 16:55:04 +02:00
2017-12-08 18:35:59 +01:00
private String escapeString(String str) {
if (str.contains("[CDATA")) {
return str;
}
2018-07-30 04:07:02 +02:00
return str.replace("<", "&lt;").replace(">", "&gt;").replace("& ", "&amp; ");
2017-12-08 18:35:59 +01:00
}
2019-01-23 18:03:33 +01:00
public void saveRemoteLocaleStringsForCurrentLocale(final TLRPC.TL_langPackDifference difference, int currentAccount) {
if (currentLocaleInfo == null) {
2017-12-08 18:35:59 +01:00
return;
}
final String langCode = difference.lang_code.replace('-', '_').toLowerCase();
2019-01-23 18:03:33 +01:00
if (!langCode.equals(currentLocaleInfo.shortName) && !langCode.equals(currentLocaleInfo.baseLangCode)) {
2018-07-30 04:07:02 +02:00
return;
}
2019-01-23 18:03:33 +01:00
saveRemoteLocaleStrings(currentLocaleInfo, difference, currentAccount);
}
public void saveRemoteLocaleStrings(LocaleInfo localeInfo, final TLRPC.TL_langPackDifference difference, int currentAccount) {
if (difference == null || difference.strings.isEmpty() || localeInfo == null || localeInfo.isLocal()) {
return;
}
final String langCode = difference.lang_code.replace('-', '_').toLowerCase();
int type;
if (langCode.equals(localeInfo.shortName)) {
type = 0;
} else if (langCode.equals(localeInfo.baseLangCode)) {
type = 1;
} else {
type = -1;
}
if (type == -1) {
return;
}
File finalFile;
if (type == 0) {
finalFile = localeInfo.getPathToFile();
} else {
finalFile = localeInfo.getPathToBaseFile();
}
2017-07-08 18:32:04 +02:00
try {
final HashMap<String, String> values;
if (difference.from_version == 0) {
values = new HashMap<>();
} else {
values = getLocaleFileStrings(finalFile, true);
}
for (int a = 0; a < difference.strings.size(); a++) {
TLRPC.LangPackString string = difference.strings.get(a);
if (string instanceof TLRPC.TL_langPackString) {
2017-12-08 18:35:59 +01:00
values.put(string.key, escapeString(string.value));
2017-07-08 18:32:04 +02:00
} else if (string instanceof TLRPC.TL_langPackStringPluralized) {
2017-12-08 18:35:59 +01:00
values.put(string.key + "_zero", string.zero_value != null ? escapeString(string.zero_value) : "");
values.put(string.key + "_one", string.one_value != null ? escapeString(string.one_value) : "");
values.put(string.key + "_two", string.two_value != null ? escapeString(string.two_value) : "");
values.put(string.key + "_few", string.few_value != null ? escapeString(string.few_value) : "");
values.put(string.key + "_many", string.many_value != null ? escapeString(string.many_value) : "");
values.put(string.key + "_other", string.other_value != null ? escapeString(string.other_value) : "");
2017-07-08 18:32:04 +02:00
} else if (string instanceof TLRPC.TL_langPackStringDeleted) {
values.remove(string.key);
}
}
2018-07-30 04:07:02 +02:00
if (BuildVars.LOGS_ENABLED) {
FileLog.d("save locale file to " + finalFile);
}
2017-07-08 18:32:04 +02:00
BufferedWriter writer = new BufferedWriter(new FileWriter(finalFile));
writer.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
writer.write("<resources>\n");
for (HashMap.Entry<String, String> entry : values.entrySet()) {
writer.write(String.format("<string name=\"%1$s\">%2$s</string>\n", entry.getKey(), entry.getValue()));
}
writer.write("</resources>");
writer.close();
2019-01-23 18:03:33 +01:00
boolean hasBase = localeInfo.hasBaseLang();
final HashMap<String, String> valuesToSet = getLocaleFileStrings(hasBase ? localeInfo.getPathToBaseFile() : localeInfo.getPathToFile());
if (hasBase) {
valuesToSet.putAll(getLocaleFileStrings(localeInfo.getPathToFile()));
}
2018-08-27 10:33:11 +02:00
AndroidUtilities.runOnUIThread(() -> {
2020-10-30 11:26:29 +01:00
if (type == 0) {
localeInfo.version = difference.version;
} else {
localeInfo.baseVersion = difference.version;
2018-08-27 10:33:11 +02:00
}
saveOtherLanguages();
try {
2019-01-23 18:03:33 +01:00
if (currentLocaleInfo == localeInfo) {
Locale newLocale;
String[] args;
if (!TextUtils.isEmpty(localeInfo.pluralLangCode)) {
args = localeInfo.pluralLangCode.split("_");
} else if (!TextUtils.isEmpty(localeInfo.baseLangCode)) {
args = localeInfo.baseLangCode.split("_");
} else {
args = localeInfo.shortName.split("_");
}
if (args.length == 1) {
newLocale = new Locale(args[0]);
} else {
newLocale = new Locale(args[0], args[1]);
}
2020-10-30 11:26:29 +01:00
languageOverride = localeInfo.shortName;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putString("language", localeInfo.getKey());
Merge remote-tracking branch 'upstream/master' # Conflicts: # TMessagesProj/build.gradle # TMessagesProj/src/main/AndroidManifest.xml # TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java # TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java # TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java # TMessagesProj/src/main/java/org/telegram/messenger/LocaleController.java # TMessagesProj/src/main/java/org/telegram/messenger/MediaDataController.java # TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java # TMessagesProj/src/main/java/org/telegram/messenger/SendMessagesHelper.java # TMessagesProj/src/main/java/org/telegram/tgnet/ConnectionsManager.java # TMessagesProj/src/main/java/org/telegram/ui/ActionBar/ActionBarPopupWindow.java # TMessagesProj/src/main/java/org/telegram/ui/ActionBar/Theme.java # TMessagesProj/src/main/java/org/telegram/ui/Adapters/DialogsSearchAdapter.java # TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java # TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java # TMessagesProj/src/main/java/org/telegram/ui/Cells/DrawerProfileCell.java # TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java # TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java # TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java # TMessagesProj/src/main/java/org/telegram/ui/Components/Bulletin.java # TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java # TMessagesProj/src/main/java/org/telegram/ui/Components/FragmentContextView.java # TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java # TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java # TMessagesProj/src/main/java/org/telegram/ui/PaymentFormActivity.java # TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java # TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java # build.gradle # gradle/wrapper/gradle-wrapper.properties
2020-10-30 15:57:47 +01:00
editor.apply();
2020-10-30 11:26:29 +01:00
localeValues = valuesToSet;
currentLocale = newLocale;
currentLocaleInfo = localeInfo;
if (!TextUtils.isEmpty(currentLocaleInfo.pluralLangCode)) {
currentPluralRules = allRules.get(currentLocaleInfo.pluralLangCode);
2019-01-23 18:03:33 +01:00
}
2020-10-30 11:26:29 +01:00
if (currentPluralRules == null) {
currentPluralRules = allRules.get(currentLocale.getLanguage());
2019-01-23 18:03:33 +01:00
if (currentPluralRules == null) {
2020-10-30 11:26:29 +01:00
currentPluralRules = allRules.get("en");
2019-01-23 18:03:33 +01:00
}
2017-07-08 18:32:04 +02:00
}
2020-10-30 11:26:29 +01:00
changingConfiguration = true;
Locale.setDefault(currentLocale);
Configuration config = new Configuration();
config.locale = currentLocale;
ApplicationLoader.applicationContext.getResources().updateConfiguration(config, ApplicationLoader.applicationContext.getResources().getDisplayMetrics());
changingConfiguration = false;
2017-07-08 18:32:04 +02:00
}
2018-08-27 10:33:11 +02:00
} catch (Exception e) {
FileLog.e(e);
changingConfiguration = false;
2017-07-08 18:32:04 +02:00
}
2018-08-27 10:33:11 +02:00
recreateFormatters();
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.reloadInterface);
2017-07-08 18:32:04 +02:00
});
} catch (Exception ignore) {
}
}
2018-07-30 04:07:02 +02:00
public void loadRemoteLanguages(final int currentAccount) {
2017-07-08 18:32:04 +02:00
if (loadingRemoteLanguages) {
return;
}
loadingRemoteLanguages = true;
TLRPC.TL_langpack_getLanguages req = new TLRPC.TL_langpack_getLanguages();
2018-08-27 10:33:11 +02:00
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (response != null) {
AndroidUtilities.runOnUIThread(() -> {
loadingRemoteLanguages = false;
TLRPC.Vector res = (TLRPC.Vector) response;
2019-01-23 18:03:33 +01:00
for (int a = 0, size = remoteLanguages.size(); a < size; a++) {
remoteLanguages.get(a).serverIndex = Integer.MAX_VALUE;
}
for (int a = 0, size = res.objects.size(); a < size; a++) {
2018-08-27 10:33:11 +02:00
TLRPC.TL_langPackLanguage language = (TLRPC.TL_langPackLanguage) res.objects.get(a);
if (BuildVars.LOGS_ENABLED) {
FileLog.d("loaded lang " + language.name);
FileLog.d(GsonUtil.formatObject(language));
2018-08-27 10:33:11 +02:00
}
LocaleInfo localeInfo = new LocaleInfo();
localeInfo.nameEnglish = language.name;
localeInfo.name = language.native_name;
localeInfo.shortName = language.lang_code.replace('-', '_').toLowerCase();
2019-01-23 18:03:33 +01:00
if (language.base_lang_code != null) {
localeInfo.baseLangCode = language.base_lang_code.replace('-', '_').toLowerCase();
} else {
localeInfo.baseLangCode = "";
}
localeInfo.pluralLangCode = language.plural_code.replace('-', '_').toLowerCase();
localeInfo.isRtl = language.rtl;
2018-08-27 10:33:11 +02:00
localeInfo.pathToFile = "remote";
2019-01-23 18:03:33 +01:00
localeInfo.serverIndex = a;
2018-08-27 10:33:11 +02:00
LocaleInfo existing = getLanguageFromDict(localeInfo.getKey());
if (existing == null) {
languages.add(localeInfo);
languagesDict.put(localeInfo.getKey(), localeInfo);
} else {
existing.nameEnglish = localeInfo.nameEnglish;
existing.name = localeInfo.name;
2019-01-23 18:03:33 +01:00
existing.baseLangCode = localeInfo.baseLangCode;
existing.pluralLangCode = localeInfo.pluralLangCode;
2018-08-27 10:33:11 +02:00
existing.pathToFile = localeInfo.pathToFile;
2019-01-23 18:03:33 +01:00
existing.serverIndex = localeInfo.serverIndex;
2018-08-27 10:33:11 +02:00
localeInfo = existing;
}
2019-01-23 18:03:33 +01:00
if (!remoteLanguagesDict.containsKey(localeInfo.getKey())) {
remoteLanguages.add(localeInfo);
remoteLanguagesDict.put(localeInfo.getKey(), localeInfo);
}
2018-08-27 10:33:11 +02:00
}
2019-01-23 18:03:33 +01:00
for (int a = 0; a < remoteLanguages.size(); a++) {
LocaleInfo info = remoteLanguages.get(a);
if (info.serverIndex != Integer.MAX_VALUE || info == currentLocaleInfo) {
2018-08-27 10:33:11 +02:00
continue;
}
2019-01-23 18:03:33 +01:00
if (BuildVars.LOGS_ENABLED) {
FileLog.d("remove lang " + info.getKey());
2017-07-08 18:32:04 +02:00
}
2019-01-23 18:03:33 +01:00
remoteLanguages.remove(a);
remoteLanguagesDict.remove(info.getKey());
languages.remove(info);
languagesDict.remove(info.getKey());
a--;
2018-08-27 10:33:11 +02:00
}
saveOtherLanguages();
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.suggestedLangpack);
applyLanguage(currentLocaleInfo, true, false, currentAccount);
});
2017-07-08 18:32:04 +02:00
}
}, ConnectionsManager.RequestFlagWithoutLogin);
}
2019-01-23 18:03:33 +01:00
private void applyRemoteLanguage(LocaleInfo localeInfo, String langCode, boolean force, final int currentAccount) {
2020-10-30 11:26:29 +01:00
if (localeInfo == null || !localeInfo.isRemote() && !localeInfo.isUnofficial()) {
2017-07-08 18:32:04 +02:00
return;
}
2019-01-23 18:03:33 +01:00
if (localeInfo.hasBaseLang() && (langCode == null || langCode.equals(localeInfo.baseLangCode))) {
if (localeInfo.baseVersion != 0 && !force) {
if (localeInfo.hasBaseLang()) {
TLRPC.TL_langpack_getDifference req = new TLRPC.TL_langpack_getDifference();
req.from_version = localeInfo.baseVersion;
2019-05-14 14:08:05 +02:00
req.lang_code = localeInfo.getBaseLangCode();
req.lang_pack = "";
2019-01-23 18:03:33 +01:00
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (response != null) {
2020-06-25 17:28:24 +02:00
saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount);
2019-01-23 18:03:33 +01:00
}
}, ConnectionsManager.RequestFlagWithoutLogin);
2017-07-08 18:32:04 +02:00
}
2019-01-23 18:03:33 +01:00
} else {
TLRPC.TL_langpack_getLangPack req = new TLRPC.TL_langpack_getLangPack();
req.lang_code = localeInfo.getBaseLangCode();
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (TLObject response, TLRPC.TL_error error) -> {
if (response != null) {
2020-06-25 17:28:24 +02:00
saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount);
2019-01-23 18:03:33 +01:00
}
}, ConnectionsManager.RequestFlagWithoutLogin);
}
}
if (langCode == null || langCode.equals(localeInfo.shortName)) {
if (localeInfo.version != 0 && !force) {
TLRPC.TL_langpack_getDifference req = new TLRPC.TL_langpack_getDifference();
req.from_version = localeInfo.version;
2019-05-14 14:08:05 +02:00
req.lang_code = localeInfo.getLangCode();
req.lang_pack = "";
2019-01-23 18:03:33 +01:00
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (response != null) {
2020-06-25 17:28:24 +02:00
saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount);
2019-01-23 18:03:33 +01:00
}
}, ConnectionsManager.RequestFlagWithoutLogin);
} else {
2021-03-12 13:37:39 +01:00
ConnectionsManager.setLangCode(localeInfo.getLangCode());
2019-01-23 18:03:33 +01:00
TLRPC.TL_langpack_getLangPack req = new TLRPC.TL_langpack_getLangPack();
req.lang_code = localeInfo.getLangCode();
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (TLObject response, TLRPC.TL_error error) -> {
if (response != null) {
2020-06-25 17:28:24 +02:00
saveRemoteLocaleStrings(localeInfo, (TLRPC.TL_langPackDifference) response, currentAccount);
2019-01-23 18:03:33 +01:00
}
}, ConnectionsManager.RequestFlagWithoutLogin);
}
2017-07-08 18:32:04 +02:00
}
}
2020-06-25 17:28:24 +02:00
private static String[] prebuilt;
private void loadPrebuiltLocaleFile(LocaleInfo localeInfo) {
if (prebuilt == null) {
try {
AssetManager assets = ApplicationLoader.applicationContext.getAssets();
prebuilt = assets.list("languages");
} catch (IOException e) {
FileLog.e(e);
return;
}
}
if (prebuilt == null) {
FileLog.w("empty prebuilt languages list");
return;
}
File pathToFile = localeInfo.getPathToFile();
File pathToBaseFile = localeInfo.getPathToBaseFile();
if ((pathToFile != null && !pathToFile.isFile()) || (pathToBaseFile != null && !pathToBaseFile.isFile())) {
try {
if (pathToBaseFile != null && !pathToBaseFile.isFile() && ArrayUtils.contains(prebuilt, pathToBaseFile.getName())) {
FileUtil.saveAsset("languages/" + pathToBaseFile.getName(), pathToBaseFile);
}
if (pathToFile != null && !pathToFile.isFile() && ArrayUtils.contains(prebuilt, pathToFile.getName())) {
FileUtil.saveAsset("languages/" + pathToFile.getName(), pathToFile);
}
} catch (Exception e) {
FileLog.e(e);
}
}
}
2015-02-01 19:51:02 +01:00
public String getTranslitString(String src) {
2019-05-14 14:08:05 +02:00
return getTranslitString(src, true, false);
2018-08-27 10:33:11 +02:00
}
public String getTranslitString(String src, boolean onlyEnglish) {
2019-05-14 14:08:05 +02:00
return getTranslitString(src, true, onlyEnglish);
}
public String getTranslitString(String src, boolean ru, boolean onlyEnglish) {
2018-08-27 10:33:11 +02:00
if (src == null) {
return null;
}
2019-05-14 14:08:05 +02:00
if (ruTranslitChars == null) {
ruTranslitChars = new HashMap<>(33);
ruTranslitChars.put("а", "a");
ruTranslitChars.put("б", "b");
ruTranslitChars.put("в", "v");
ruTranslitChars.put("г", "g");
ruTranslitChars.put("д", "d");
ruTranslitChars.put("е", "e");
ruTranslitChars.put("ё", "yo");
ruTranslitChars.put("ж", "zh");
ruTranslitChars.put("з", "z");
ruTranslitChars.put("и", "i");
ruTranslitChars.put("й", "i");
ruTranslitChars.put("к", "k");
ruTranslitChars.put("л", "l");
ruTranslitChars.put("м", "m");
ruTranslitChars.put("н", "n");
ruTranslitChars.put("о", "o");
ruTranslitChars.put("п", "p");
ruTranslitChars.put("р", "r");
ruTranslitChars.put("с", "s");
ruTranslitChars.put("т", "t");
ruTranslitChars.put("у", "u");
ruTranslitChars.put("ф", "f");
ruTranslitChars.put("х", "h");
ruTranslitChars.put("ц", "ts");
ruTranslitChars.put("ч", "ch");
ruTranslitChars.put("ш", "sh");
ruTranslitChars.put("щ", "sch");
ruTranslitChars.put("ы", "i");
ruTranslitChars.put("ь", "");
ruTranslitChars.put("ъ", "");
ruTranslitChars.put("э", "e");
ruTranslitChars.put("ю", "yu");
ruTranslitChars.put("я", "ya");
}
2015-02-01 19:51:02 +01:00
if (translitChars == null) {
2019-05-14 14:08:05 +02:00
translitChars = new HashMap<>(487);
2015-02-01 19:51:02 +01:00
translitChars.put("ȼ", "c");
translitChars.put("", "n");
translitChars.put("ɖ", "d");
translitChars.put("ỿ", "y");
translitChars.put("", "o");
translitChars.put("ø", "o");
translitChars.put("", "a");
translitChars.put("ʯ", "h");
translitChars.put("ŷ", "y");
translitChars.put("ʞ", "k");
translitChars.put("", "u");
translitChars.put("", "aa");
translitChars.put("ij", "ij");
translitChars.put("", "l");
translitChars.put("ɪ", "i");
translitChars.put("", "b");
translitChars.put("ʀ", "r");
translitChars.put("ě", "e");
translitChars.put("", "ffi");
translitChars.put("ơ", "o");
translitChars.put("", "r");
translitChars.put("", "o");
translitChars.put("ǐ", "i");
translitChars.put("", "p");
translitChars.put("ý", "y");
translitChars.put("", "e");
translitChars.put("", "o");
translitChars.put("", "a");
translitChars.put("ʙ", "b");
translitChars.put("", "e");
translitChars.put("ƈ", "c");
translitChars.put("ɦ", "h");
translitChars.put("", "b");
translitChars.put("", "s");
translitChars.put("đ", "d");
translitChars.put("", "o");
translitChars.put("ɟ", "j");
translitChars.put("", "a");
translitChars.put("ɏ", "y");
translitChars.put("ʌ", "v");
translitChars.put("", "p");
translitChars.put("", "fi");
translitChars.put("", "k");
translitChars.put("", "d");
translitChars.put("", "l");
translitChars.put("ė", "e");
translitChars.put("", "k");
translitChars.put("ċ", "c");
translitChars.put("ʁ", "r");
translitChars.put("ƕ", "hv");
translitChars.put("ƀ", "b");
translitChars.put("", "o");
translitChars.put("ȣ", "ou");
translitChars.put("ǰ", "j");
translitChars.put("", "g");
translitChars.put("", "n");
translitChars.put("ɉ", "j");
translitChars.put("ǧ", "g");
translitChars.put("dz", "dz");
translitChars.put("ź", "z");
translitChars.put("", "au");
translitChars.put("ǖ", "u");
translitChars.put("", "g");
translitChars.put("ȯ", "o");
translitChars.put("ɐ", "a");
translitChars.put("ą", "a");
translitChars.put("õ", "o");
translitChars.put("ɻ", "r");
translitChars.put("", "o");
translitChars.put("ǟ", "a");
translitChars.put("ȴ", "l");
translitChars.put("ʂ", "s");
translitChars.put("", "fl");
translitChars.put("ȉ", "i");
translitChars.put("", "e");
translitChars.put("", "n");
translitChars.put("ï", "i");
translitChars.put("ñ", "n");
translitChars.put("", "i");
translitChars.put("ʇ", "t");
translitChars.put("", "z");
translitChars.put("", "y");
translitChars.put("ȳ", "y");
translitChars.put("", "s");
translitChars.put("ɽ", "r");
translitChars.put("ĝ", "g");
translitChars.put("", "u");
translitChars.put("", "k");
translitChars.put("", "et");
translitChars.put("ī", "i");
translitChars.put("ť", "t");
translitChars.put("", "c");
translitChars.put("ʟ", "l");
translitChars.put("", "av");
translitChars.put("û", "u");
translitChars.put("æ", "ae");
translitChars.put("ă", "a");
translitChars.put("ǘ", "u");
translitChars.put("", "s");
translitChars.put("", "r");
translitChars.put("", "a");
translitChars.put("ƃ", "b");
translitChars.put("", "h");
translitChars.put("", "s");
translitChars.put("", "e");
translitChars.put("ʜ", "h");
translitChars.put("", "x");
translitChars.put("", "k");
translitChars.put("", "d");
translitChars.put("ƣ", "oi");
translitChars.put("", "p");
translitChars.put("ħ", "h");
translitChars.put("", "v");
translitChars.put("", "w");
translitChars.put("ǹ", "n");
translitChars.put("ɯ", "m");
translitChars.put("ɡ", "g");
translitChars.put("ɴ", "n");
translitChars.put("", "p");
translitChars.put("", "v");
translitChars.put("ū", "u");
translitChars.put("", "b");
translitChars.put("", "p");
translitChars.put("å", "a");
translitChars.put("ɕ", "c");
translitChars.put("", "o");
translitChars.put("", "a");
translitChars.put("ƒ", "f");
translitChars.put("ǣ", "ae");
translitChars.put("", "vy");
translitChars.put("", "ff");
translitChars.put("", "r");
translitChars.put("ô", "o");
translitChars.put("ǿ", "o");
translitChars.put("", "u");
translitChars.put("ȥ", "z");
translitChars.put("", "f");
translitChars.put("", "d");
translitChars.put("ȇ", "e");
translitChars.put("ȕ", "u");
translitChars.put("ȵ", "n");
translitChars.put("ʠ", "q");
translitChars.put("", "a");
translitChars.put("ǩ", "k");
translitChars.put("ĩ", "i");
translitChars.put("", "u");
translitChars.put("ŧ", "t");
translitChars.put("ɾ", "r");
translitChars.put("ƙ", "k");
translitChars.put("", "t");
translitChars.put("", "q");
translitChars.put("", "a");
translitChars.put("ʄ", "j");
translitChars.put("ƚ", "l");
translitChars.put("", "f");
translitChars.put("", "s");
translitChars.put("", "r");
translitChars.put("", "v");
translitChars.put("ɵ", "o");
translitChars.put("", "c");
translitChars.put("", "u");
translitChars.put("", "z");
translitChars.put("", "u");
translitChars.put("ň", "n");
translitChars.put("ʍ", "w");
translitChars.put("", "a");
translitChars.put("lj", "lj");
translitChars.put("ɓ", "b");
translitChars.put("ɼ", "r");
translitChars.put("ò", "o");
translitChars.put("", "w");
translitChars.put("ɗ", "d");
translitChars.put("", "ay");
translitChars.put("ư", "u");
translitChars.put("", "b");
translitChars.put("ǜ", "u");
translitChars.put("", "e");
translitChars.put("ǡ", "a");
translitChars.put("ɥ", "h");
translitChars.put("", "o");
translitChars.put("ǔ", "u");
translitChars.put("ʎ", "y");
translitChars.put("ȱ", "o");
translitChars.put("", "e");
translitChars.put("ế", "e");
translitChars.put("ĭ", "i");
translitChars.put("", "e");
translitChars.put("", "t");
translitChars.put("", "d");
translitChars.put("", "h");
translitChars.put("", "s");
translitChars.put("ë", "e");
translitChars.put("", "m");
translitChars.put("ö", "o");
translitChars.put("é", "e");
translitChars.put("ı", "i");
translitChars.put("ď", "d");
translitChars.put("", "m");
translitChars.put("", "y");
translitChars.put("ŵ", "w");
translitChars.put("", "e");
translitChars.put("", "u");
translitChars.put("ƶ", "z");
translitChars.put("ĵ", "j");
translitChars.put("", "d");
translitChars.put("ŭ", "u");
translitChars.put("ʝ", "j");
translitChars.put("ê", "e");
translitChars.put("ǚ", "u");
translitChars.put("ġ", "g");
translitChars.put("", "r");
translitChars.put("ƞ", "n");
translitChars.put("", "e");
translitChars.put("", "s");
translitChars.put("", "d");
translitChars.put("ķ", "k");
translitChars.put("", "ae");
translitChars.put("ɘ", "e");
translitChars.put("", "o");
translitChars.put("ḿ", "m");
translitChars.put("", "f");
translitChars.put("", "a");
translitChars.put("", "oo");
translitChars.put("", "m");
translitChars.put("", "p");
translitChars.put("", "u");
translitChars.put("", "k");
translitChars.put("", "h");
translitChars.put("ţ", "t");
translitChars.put("", "p");
translitChars.put("", "m");
translitChars.put("á", "a");
translitChars.put("", "n");
translitChars.put("", "v");
translitChars.put("è", "e");
translitChars.put("", "z");
translitChars.put("", "d");
translitChars.put("", "p");
translitChars.put("ɫ", "l");
translitChars.put("", "z");
translitChars.put("ɱ", "m");
translitChars.put("", "r");
translitChars.put("", "v");
translitChars.put("ũ", "u");
translitChars.put("ß", "ss");
translitChars.put("ĥ", "h");
translitChars.put("", "t");
translitChars.put("ʐ", "z");
translitChars.put("", "r");
translitChars.put("ɲ", "n");
translitChars.put("à", "a");
translitChars.put("", "y");
translitChars.put("", "y");
translitChars.put("", "oe");
translitChars.put("", "x");
translitChars.put("ȗ", "u");
translitChars.put("", "j");
translitChars.put("", "a");
translitChars.put("ʑ", "z");
translitChars.put("", "s");
translitChars.put("", "i");
translitChars.put("", "ao");
translitChars.put("ɀ", "z");
translitChars.put("ÿ", "y");
translitChars.put("ǝ", "e");
translitChars.put("ǭ", "o");
translitChars.put("", "d");
translitChars.put("", "l");
translitChars.put("ù", "u");
translitChars.put("", "a");
translitChars.put("", "b");
translitChars.put("", "u");
translitChars.put("", "a");
translitChars.put("", "t");
translitChars.put("ƴ", "y");
translitChars.put("", "t");
translitChars.put("", "l");
translitChars.put("ȷ", "j");
translitChars.put("", "z");
translitChars.put("", "h");
translitChars.put("", "w");
translitChars.put("", "k");
translitChars.put("", "o");
translitChars.put("î", "i");
translitChars.put("ģ", "g");
translitChars.put("ȅ", "e");
translitChars.put("ȧ", "a");
translitChars.put("", "a");
translitChars.put("ɋ", "q");
translitChars.put("", "t");
translitChars.put("", "um");
translitChars.put("", "c");
translitChars.put("", "x");
translitChars.put("", "u");
translitChars.put("", "i");
translitChars.put("", "r");
translitChars.put("ś", "s");
translitChars.put("", "o");
translitChars.put("", "y");
translitChars.put("", "s");
translitChars.put("nj", "nj");
translitChars.put("ȁ", "a");
translitChars.put("", "t");
translitChars.put("ĺ", "l");
translitChars.put("ž", "z");
translitChars.put("", "th");
translitChars.put("ƌ", "d");
translitChars.put("ș", "s");
translitChars.put("š", "s");
translitChars.put("", "u");
translitChars.put("", "e");
translitChars.put("", "s");
translitChars.put("ɇ", "e");
translitChars.put("", "u");
translitChars.put("", "o");
translitChars.put("ȿ", "s");
translitChars.put("", "v");
translitChars.put("", "is");
translitChars.put("", "o");
translitChars.put("ɛ", "e");
translitChars.put("ǻ", "a");
translitChars.put("", "ffl");
translitChars.put("", "o");
translitChars.put("ȋ", "i");
translitChars.put("", "ue");
translitChars.put("ȡ", "d");
translitChars.put("", "z");
translitChars.put("", "w");
translitChars.put("", "a");
translitChars.put("", "t");
translitChars.put("ğ", "g");
translitChars.put("ɳ", "n");
translitChars.put("ʛ", "g");
translitChars.put("", "u");
translitChars.put("", "a");
translitChars.put("", "n");
translitChars.put("ɨ", "i");
translitChars.put("", "r");
translitChars.put("ǎ", "a");
translitChars.put("ſ", "s");
translitChars.put("ȫ", "o");
translitChars.put("ɿ", "r");
translitChars.put("ƭ", "t");
translitChars.put("", "i");
translitChars.put("ǽ", "ae");
translitChars.put("", "v");
translitChars.put("ɶ", "oe");
translitChars.put("", "m");
translitChars.put("ż", "z");
translitChars.put("ĕ", "e");
translitChars.put("", "av");
translitChars.put("", "o");
translitChars.put("", "e");
translitChars.put("ɬ", "l");
translitChars.put("", "i");
translitChars.put("", "d");
translitChars.put("", "st");
translitChars.put("", "l");
translitChars.put("ŕ", "r");
translitChars.put("", "ou");
translitChars.put("ʈ", "t");
translitChars.put("ā", "a");
translitChars.put("", "e");
translitChars.put("", "o");
translitChars.put("ç", "c");
translitChars.put("", "s");
translitChars.put("", "a");
translitChars.put("ų", "u");
translitChars.put("", "a");
translitChars.put("ǥ", "g");
translitChars.put("", "k");
translitChars.put("", "z");
translitChars.put("ŝ", "s");
translitChars.put("", "e");
translitChars.put("ɠ", "g");
translitChars.put("", "l");
translitChars.put("", "f");
translitChars.put("", "x");
translitChars.put("ǒ", "o");
translitChars.put("ę", "e");
translitChars.put("", "o");
translitChars.put("ƫ", "t");
translitChars.put("ǫ", "o");
translitChars.put("", "i");
translitChars.put("", "n");
translitChars.put("ć", "c");
translitChars.put("", "g");
translitChars.put("", "w");
translitChars.put("", "d");
translitChars.put("", "l");
translitChars.put("œ", "oe");
translitChars.put("", "r");
translitChars.put("ļ", "l");
translitChars.put("ȑ", "r");
translitChars.put("ȭ", "o");
translitChars.put("", "n");
translitChars.put("", "ae");
translitChars.put("ŀ", "l");
translitChars.put("ä", "a");
translitChars.put("ƥ", "p");
translitChars.put("", "o");
translitChars.put("į", "i");
translitChars.put("ȓ", "r");
translitChars.put("dž", "dz");
translitChars.put("", "g");
translitChars.put("", "u");
translitChars.put("ō", "o");
translitChars.put("ľ", "l");
translitChars.put("", "w");
translitChars.put("ț", "t");
translitChars.put("ń", "n");
translitChars.put("ɍ", "r");
translitChars.put("ȃ", "a");
translitChars.put("ü", "u");
translitChars.put("", "l");
translitChars.put("", "o");
translitChars.put("", "o");
translitChars.put("", "b");
translitChars.put("ɹ", "r");
translitChars.put("", "r");
translitChars.put("ʏ", "y");
translitChars.put("", "f");
translitChars.put("", "h");
translitChars.put("ŏ", "o");
translitChars.put("ú", "u");
translitChars.put("", "r");
translitChars.put("ʮ", "h");
translitChars.put("ó", "o");
translitChars.put("ů", "u");
translitChars.put("", "o");
translitChars.put("", "p");
translitChars.put("", "i");
translitChars.put("", "u");
translitChars.put("ã", "a");
translitChars.put("", "i");
translitChars.put("", "t");
translitChars.put("", "e");
translitChars.put("", "u");
translitChars.put("í", "i");
translitChars.put("ɔ", "o");
translitChars.put("ɺ", "r");
translitChars.put("ɢ", "g");
translitChars.put("ř", "r");
translitChars.put("", "h");
translitChars.put("ű", "u");
translitChars.put("ȍ", "o");
translitChars.put("", "l");
translitChars.put("", "h");
translitChars.put("ȶ", "t");
translitChars.put("ņ", "n");
translitChars.put("", "e");
translitChars.put("ì", "i");
translitChars.put("", "w");
translitChars.put("ē", "e");
translitChars.put("", "e");
translitChars.put("ł", "l");
translitChars.put("", "o");
translitChars.put("ɭ", "l");
translitChars.put("", "y");
translitChars.put("", "j");
translitChars.put("", "k");
translitChars.put("ṿ", "v");
translitChars.put("ȩ", "e");
translitChars.put("â", "a");
translitChars.put("ş", "s");
translitChars.put("ŗ", "r");
translitChars.put("ʋ", "v");
translitChars.put("", "a");
translitChars.put("", "c");
translitChars.put("", "e");
translitChars.put("ɰ", "m");
translitChars.put("", "w");
translitChars.put("ȏ", "o");
translitChars.put("č", "c");
translitChars.put("ǵ", "g");
translitChars.put("ĉ", "c");
translitChars.put("", "o");
translitChars.put("", "k");
translitChars.put("", "q");
translitChars.put("", "o");
translitChars.put("", "s");
translitChars.put("", "o");
translitChars.put("ȟ", "h");
translitChars.put("ő", "o");
translitChars.put("", "tz");
translitChars.put("", "e");
}
StringBuilder dst = new StringBuilder(src.length());
int len = src.length();
2018-08-27 10:33:11 +02:00
boolean upperCase = false;
2015-02-01 19:51:02 +01:00
for (int a = 0; a < len; a++) {
String ch = src.substring(a, a + 1);
2018-08-27 10:33:11 +02:00
if (onlyEnglish) {
String lower = ch.toLowerCase();
upperCase = !ch.equals(lower);
ch = lower;
}
2015-02-01 19:51:02 +01:00
String tch = translitChars.get(ch);
2019-05-14 14:08:05 +02:00
if (tch == null && ru) {
tch = ruTranslitChars.get(ch);
}
2015-02-01 19:51:02 +01:00
if (tch != null) {
2018-08-27 10:33:11 +02:00
if (onlyEnglish && upperCase) {
if (tch.length() > 1) {
tch = tch.substring(0, 1).toUpperCase() + tch.substring(1);
} else {
tch = tch.toUpperCase();
}
}
2015-02-01 19:51:02 +01:00
dst.append(tch);
} else {
2018-08-27 10:33:11 +02:00
if (onlyEnglish) {
char c = ch.charAt(0);
if (((c < 'a' || c > 'z') || (c < '0' || c > '9')) && c != ' ' && c != '\'' && c != ',' && c != '.' && c != '&' && c != '-' && c != '/') {
return null;
}
if (upperCase) {
ch = ch.toUpperCase();
}
}
2015-02-01 19:51:02 +01:00
dst.append(ch);
}
}
return dst.toString();
}
2014-07-03 16:55:04 +02:00
abstract public static class PluralRules {
abstract int quantityForNumber(int n);
}
public static class PluralRules_Zero extends PluralRules {
public int quantityForNumber(int count) {
if (count == 0 || count == 1) {
return QUANTITY_ONE;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Welsh extends PluralRules {
public int quantityForNumber(int count) {
if (count == 0) {
return QUANTITY_ZERO;
} else if (count == 1) {
return QUANTITY_ONE;
} else if (count == 2) {
return QUANTITY_TWO;
} else if (count == 3) {
return QUANTITY_FEW;
} else if (count == 6) {
return QUANTITY_MANY;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Two extends PluralRules {
public int quantityForNumber(int count) {
if (count == 1) {
return QUANTITY_ONE;
} else if (count == 2) {
return QUANTITY_TWO;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Tachelhit extends PluralRules {
public int quantityForNumber(int count) {
if (count >= 0 && count <= 1) {
return QUANTITY_ONE;
} else if (count >= 2 && count <= 10) {
return QUANTITY_FEW;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Slovenian extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
if (rem100 == 1) {
return QUANTITY_ONE;
} else if (rem100 == 2) {
return QUANTITY_TWO;
} else if (rem100 >= 3 && rem100 <= 4) {
return QUANTITY_FEW;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Romanian extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
if (count == 1) {
return QUANTITY_ONE;
} else if ((count == 0 || (rem100 >= 1 && rem100 <= 19))) {
return QUANTITY_FEW;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Polish extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
int rem10 = count % 10;
if (count == 1) {
return QUANTITY_ONE;
2019-01-23 18:03:33 +01:00
} else if (rem10 >= 2 && rem10 <= 4 && !(rem100 >= 12 && rem100 <= 14)) {
2014-07-03 16:55:04 +02:00
return QUANTITY_FEW;
2019-01-23 18:03:33 +01:00
} else if (rem10 >= 0 && rem10 <= 1 || rem10 >= 5 && rem10 <= 9 || rem100 >= 12 && rem100 <= 14) {
return QUANTITY_MANY;
2014-07-03 16:55:04 +02:00
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_One extends PluralRules {
public int quantityForNumber(int count) {
return count == 1 ? QUANTITY_ONE : QUANTITY_OTHER;
}
}
public static class PluralRules_None extends PluralRules {
public int quantityForNumber(int count) {
return QUANTITY_OTHER;
}
}
public static class PluralRules_Maltese extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
if (count == 1) {
return QUANTITY_ONE;
} else if (count == 0 || (rem100 >= 2 && rem100 <= 10)) {
return QUANTITY_FEW;
} else if (rem100 >= 11 && rem100 <= 19) {
return QUANTITY_MANY;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Macedonian extends PluralRules {
public int quantityForNumber(int count) {
if (count % 10 == 1 && count != 11) {
return QUANTITY_ONE;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Lithuanian extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
int rem10 = count % 10;
if (rem10 == 1 && !(rem100 >= 11 && rem100 <= 19)) {
return QUANTITY_ONE;
} else if (rem10 >= 2 && rem10 <= 9 && !(rem100 >= 11 && rem100 <= 19)) {
return QUANTITY_FEW;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Latvian extends PluralRules {
public int quantityForNumber(int count) {
if (count == 0) {
return QUANTITY_ZERO;
} else if (count % 10 == 1 && count % 100 != 11) {
return QUANTITY_ONE;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Langi extends PluralRules {
public int quantityForNumber(int count) {
if (count == 0) {
return QUANTITY_ZERO;
2020-02-13 19:26:53 +01:00
} else if (count == 1) {
2014-07-03 16:55:04 +02:00
return QUANTITY_ONE;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_French extends PluralRules {
public int quantityForNumber(int count) {
if (count >= 0 && count < 2) {
return QUANTITY_ONE;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Czech extends PluralRules {
public int quantityForNumber(int count) {
if (count == 1) {
return QUANTITY_ONE;
} else if (count >= 2 && count <= 4) {
return QUANTITY_FEW;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Breton extends PluralRules {
public int quantityForNumber(int count) {
if (count == 0) {
return QUANTITY_ZERO;
} else if (count == 1) {
return QUANTITY_ONE;
} else if (count == 2) {
return QUANTITY_TWO;
} else if (count == 3) {
return QUANTITY_FEW;
} else if (count == 6) {
return QUANTITY_MANY;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Balkan extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
int rem10 = count % 10;
if (rem10 == 1 && rem100 != 11) {
return QUANTITY_ONE;
} else if (rem10 >= 2 && rem10 <= 4 && !(rem100 >= 12 && rem100 <= 14)) {
return QUANTITY_FEW;
} else if ((rem10 == 0 || (rem10 >= 5 && rem10 <= 9) || (rem100 >= 11 && rem100 <= 14))) {
return QUANTITY_MANY;
} else {
return QUANTITY_OTHER;
}
}
}
2020-10-31 22:13:37 +01:00
public static class PluralRules_Serbian extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
int rem10 = count % 10;
if (rem10 == 1 && rem100 != 11) {
return QUANTITY_ONE;
} else if (rem10 >= 2 && rem10 <= 4 && !(rem100 >= 12 && rem100 <= 14)) {
return QUANTITY_FEW;
} else {
return QUANTITY_OTHER;
}
}
}
2014-07-03 16:55:04 +02:00
public static class PluralRules_Arabic extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
if (count == 0) {
return QUANTITY_ZERO;
} else if (count == 1) {
return QUANTITY_ONE;
} else if (count == 2) {
return QUANTITY_TWO;
} else if (rem100 >= 3 && rem100 <= 10) {
return QUANTITY_FEW;
} else if (rem100 >= 11 && rem100 <= 99) {
return QUANTITY_MANY;
} else {
return QUANTITY_OTHER;
}
}
}
2018-07-30 04:07:02 +02:00
public static String addNbsp(String src) {
return src.replace(' ', '\u00A0');
}
2019-07-18 15:01:39 +02:00
private static Boolean useImperialSystemType;
public static void resetImperialSystemType() {
useImperialSystemType = null;
}
2020-10-30 11:26:29 +01:00
public static boolean getUseImperialSystemType() {
ensureImperialSystemInit();
return useImperialSystemType;
}
public static void ensureImperialSystemInit() {
if (useImperialSystemType != null) {
return;
}
if (SharedConfig.distanceSystemType == 0) {
try {
TelephonyManager telephonyManager = (TelephonyManager) ApplicationLoader.applicationContext.getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null) {
String country = telephonyManager.getSimCountryIso().toUpperCase();
useImperialSystemType = "US".equals(country) || "GB".equals(country) || "MM".equals(country) || "LR".equals(country);
2019-07-18 15:01:39 +02:00
}
2020-10-30 11:26:29 +01:00
} catch (Exception e) {
useImperialSystemType = false;
FileLog.e(e);
2019-07-18 15:01:39 +02:00
}
2020-10-30 11:26:29 +01:00
} else {
useImperialSystemType = SharedConfig.distanceSystemType == 2;
2019-07-18 15:01:39 +02:00
}
2020-10-30 11:26:29 +01:00
}
public static String formatDistance(float distance, int type) {
return formatDistance(distance, type, null);
}
public static String formatDistance(float distance, int type, Boolean useImperial) {
ensureImperialSystemInit();
boolean imperial = useImperial != null && useImperial || useImperial == null && useImperialSystemType;
if (imperial) {
2019-07-18 15:01:39 +02:00
distance *= 3.28084f;
if (distance < 1000) {
2020-07-26 10:03:38 +02:00
switch (type) {
case 0:
return formatString("FootsAway", R.string.FootsAway, String.format("%d", (int) Math.max(1, distance)));
case 1:
return formatString("FootsFromYou", R.string.FootsFromYou, String.format("%d", (int) Math.max(1, distance)));
2020-10-30 11:26:29 +01:00
case 2:
default:
return formatString("FootsShort", R.string.FootsShort, String.format("%d", (int) Math.max(1, distance)));
2020-07-26 10:03:38 +02:00
}
2019-07-18 15:01:39 +02:00
} else {
String arg;
if (distance % 5280 == 0) {
arg = String.format("%d", (int) (distance / 5280));
} else {
arg = String.format("%.2f", distance / 5280.0f);
}
2020-07-26 10:03:38 +02:00
switch (type) {
case 0:
return formatString("MilesAway", R.string.MilesAway, arg);
case 1:
return formatString("MilesFromYou", R.string.MilesFromYou, arg);
2020-10-30 11:26:29 +01:00
default:
case 2:
return formatString("MilesShort", R.string.MilesShort, arg);
2020-07-26 10:03:38 +02:00
}
2019-07-18 15:01:39 +02:00
}
} else {
if (distance < 1000) {
2020-07-26 10:03:38 +02:00
switch (type) {
case 0:
return formatString("MetersAway2", R.string.MetersAway2, String.format("%d", (int) Math.max(1, distance)));
case 1:
return formatString("MetersFromYou2", R.string.MetersFromYou2, String.format("%d", (int) Math.max(1, distance)));
2020-10-30 11:26:29 +01:00
case 2:
default:
return formatString("MetersShort", R.string.MetersShort, String.format("%d", (int) Math.max(1, distance)));
2020-07-26 10:03:38 +02:00
}
2019-07-18 15:01:39 +02:00
} else {
String arg;
if (distance % 1000 == 0) {
arg = String.format("%d", (int) (distance / 1000));
} else {
arg = String.format("%.2f", distance / 1000.0f);
}
2020-07-26 10:03:38 +02:00
switch (type) {
case 0:
return formatString("KMetersAway2", R.string.KMetersAway2, arg);
case 1:
return formatString("KMetersFromYou2", R.string.KMetersFromYou2, arg);
2020-10-30 11:26:29 +01:00
case 2:
default:
return formatString("KMetersShort", R.string.KMetersShort, arg);
2020-07-26 10:03:38 +02:00
}
2019-07-18 15:01:39 +02:00
}
}
}
}