mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
444 lines
17 KiB
Java
444 lines
17 KiB
Java
/*******************************************************************************
|
|
*
|
|
* Messenger Android Frontend
|
|
* (C) 2013-2016 Nikolai Kudashov
|
|
* (C) 2017 Björn Petersen
|
|
* Contact: r10s@b44t.com, http://b44t.com
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify it under
|
|
* the terms of the GNU General Public License as published by the Free Software
|
|
* Foundation, either version 3 of the License, or (at your option) any later
|
|
* version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program. If not, see http://www.gnu.org/licenses/ .
|
|
*
|
|
******************************************************************************/
|
|
|
|
|
|
package com.b44t.messenger;
|
|
|
|
import android.app.Activity;
|
|
import android.content.BroadcastReceiver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.IntentFilter;
|
|
import android.content.SharedPreferences;
|
|
import android.content.res.Configuration;
|
|
import android.text.format.DateFormat;
|
|
|
|
import com.b44t.messenger.time.FastDateFormat;
|
|
|
|
import java.util.Calendar;
|
|
import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.Locale;
|
|
import java.util.TimeZone;
|
|
|
|
public class LocaleController {
|
|
|
|
public static boolean isRTL = false;
|
|
public static int nameDisplayOrder = 1;
|
|
private static boolean is24HourFormat = false;
|
|
public FastDateFormat formatterDay;
|
|
public FastDateFormat formatterWeek;
|
|
public FastDateFormat formatterMonth;
|
|
public FastDateFormat formatterYear;
|
|
public FastDateFormat formatterMonthYear;
|
|
public FastDateFormat chatDate;
|
|
public FastDateFormat chatFullDate;
|
|
|
|
private Locale currentLocale;
|
|
private Locale systemDefaultLocale; // this is not Locale.getDefault(); Locale.getDefault() may be changed using Locale.setDefault()
|
|
private LocaleInfo currentLocaleInfo;
|
|
private String languageOverride;
|
|
private boolean changingConfiguration = false;
|
|
|
|
private class TimeZoneChangedReceiver extends BroadcastReceiver {
|
|
@Override
|
|
public void onReceive(Context context, Intent intent) {
|
|
ApplicationLoader.applicationHandler.post(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (!formatterMonth.getTimeZone().equals(TimeZone.getDefault())) {
|
|
LocaleController.getInstance().recreateFormatters();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
public static class LocaleInfo {
|
|
public String name;
|
|
public String nameEnglish;
|
|
public String shortName;
|
|
}
|
|
|
|
public HashMap<String, LocaleInfo> languagesDict = new HashMap<>();
|
|
|
|
private static volatile LocaleController Instance = null;
|
|
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() {
|
|
LocaleInfo localeInfo = new LocaleInfo();
|
|
localeInfo.name = "English";
|
|
localeInfo.nameEnglish = "English";
|
|
localeInfo.shortName = "en";
|
|
languagesDict.put(localeInfo.shortName, localeInfo);
|
|
|
|
localeInfo = new LocaleInfo();
|
|
localeInfo.name = "Italiano";
|
|
localeInfo.nameEnglish = "Italian";
|
|
localeInfo.shortName = "it";
|
|
languagesDict.put(localeInfo.shortName, localeInfo);
|
|
|
|
localeInfo = new LocaleInfo();
|
|
localeInfo.name = "Español";
|
|
localeInfo.nameEnglish = "Spanish";
|
|
localeInfo.shortName = "es";
|
|
languagesDict.put(localeInfo.shortName, localeInfo);
|
|
|
|
localeInfo = new LocaleInfo();
|
|
localeInfo.name = "Deutsch";
|
|
localeInfo.nameEnglish = "German";
|
|
localeInfo.shortName = "de";
|
|
languagesDict.put(localeInfo.shortName, localeInfo);
|
|
|
|
localeInfo = new LocaleInfo();
|
|
localeInfo.name = "Français";
|
|
localeInfo.nameEnglish = "French";
|
|
localeInfo.shortName = "fr";
|
|
languagesDict.put(localeInfo.shortName, localeInfo);
|
|
|
|
localeInfo = new LocaleInfo();
|
|
localeInfo.name = "Nederlands";
|
|
localeInfo.nameEnglish = "Dutch";
|
|
localeInfo.shortName = "nl";
|
|
languagesDict.put(localeInfo.shortName, localeInfo);
|
|
|
|
localeInfo = new LocaleInfo();
|
|
localeInfo.name = "Polski";
|
|
localeInfo.nameEnglish = "Polish";
|
|
localeInfo.shortName = "pl";
|
|
languagesDict.put(localeInfo.shortName, localeInfo);
|
|
|
|
localeInfo = new LocaleInfo();
|
|
localeInfo.name = "Português";
|
|
localeInfo.nameEnglish = "Portuguese";
|
|
localeInfo.shortName = "pt";
|
|
languagesDict.put(localeInfo.shortName, localeInfo);
|
|
|
|
localeInfo = new LocaleInfo();
|
|
localeInfo.name = "한국어";
|
|
localeInfo.nameEnglish = "Korean";
|
|
localeInfo.shortName = "ko";
|
|
languagesDict.put(localeInfo.shortName, localeInfo);
|
|
|
|
localeInfo = new LocaleInfo();
|
|
localeInfo.name = "Magyar";
|
|
localeInfo.nameEnglish = "Hungarian";
|
|
localeInfo.shortName = "hu";
|
|
languagesDict.put(localeInfo.shortName, localeInfo);
|
|
|
|
localeInfo = new LocaleInfo();
|
|
localeInfo.name = "Русский";
|
|
localeInfo.nameEnglish = "Russian";
|
|
localeInfo.shortName = "ru";
|
|
languagesDict.put(localeInfo.shortName, localeInfo);
|
|
|
|
systemDefaultLocale = Locale.getDefault(); // we have to remember this as we may switch back to default later
|
|
is24HourFormat = DateFormat.is24HourFormat(ApplicationLoader.applicationContext);
|
|
LocaleInfo currentInfo = null;
|
|
boolean override = false;
|
|
|
|
try {
|
|
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
|
String lang = preferences.getString("language", null);
|
|
if (lang != null) {
|
|
currentInfo = languagesDict.get(lang);
|
|
if (currentInfo != null) {
|
|
override = true;
|
|
}
|
|
}
|
|
|
|
if (currentInfo == null && systemDefaultLocale.getLanguage() != null) {
|
|
currentInfo = languagesDict.get(systemDefaultLocale.getLanguage());
|
|
}
|
|
if (currentInfo == null) {
|
|
currentInfo = languagesDict.get(getLocaleString(systemDefaultLocale));
|
|
}
|
|
if (currentInfo == null) {
|
|
currentInfo = languagesDict.get("en");
|
|
}
|
|
applyLanguage(currentInfo, override);
|
|
} catch (Exception e) {
|
|
|
|
}
|
|
|
|
try {
|
|
IntentFilter timezoneFilter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED);
|
|
ApplicationLoader.applicationContext.registerReceiver(new TimeZoneChangedReceiver(), timezoneFilter);
|
|
} catch (Exception e) {
|
|
|
|
}
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
public void applyLanguage(LocaleInfo localeInfo, boolean override) {
|
|
if (localeInfo == null) {
|
|
return;
|
|
}
|
|
try {
|
|
Locale newLocale;
|
|
if (localeInfo.shortName != null) {
|
|
String[] args = localeInfo.shortName.split("_");
|
|
if (args.length == 1) {
|
|
newLocale = new Locale(localeInfo.shortName);
|
|
} else {
|
|
newLocale = new Locale(args[0], args[1]);
|
|
}
|
|
if (newLocale != null) {
|
|
if (override) {
|
|
languageOverride = localeInfo.shortName;
|
|
|
|
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
|
SharedPreferences.Editor editor = preferences.edit();
|
|
editor.putString("language", localeInfo.shortName);
|
|
editor.apply();
|
|
}
|
|
}
|
|
} else {
|
|
newLocale = systemDefaultLocale; // this is not Locale.getDefault(); Locale.getDefault() may be changed using Locale.setDefault()
|
|
languageOverride = null;
|
|
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
|
SharedPreferences.Editor editor = preferences.edit();
|
|
editor.remove("language");
|
|
editor.apply();
|
|
|
|
if (newLocale != null) {
|
|
LocaleInfo info = null;
|
|
if (newLocale.getLanguage() != null) {
|
|
info = languagesDict.get(newLocale.getLanguage());
|
|
}
|
|
if (info == null) {
|
|
info = languagesDict.get(getLocaleString(newLocale));
|
|
}
|
|
if (info == null) {
|
|
newLocale = Locale.US;
|
|
}
|
|
}
|
|
}
|
|
if (newLocale != null) {
|
|
currentLocale = newLocale;
|
|
currentLocaleInfo = localeInfo;
|
|
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;
|
|
}
|
|
} catch (Exception e) {
|
|
|
|
changingConfiguration = false;
|
|
}
|
|
recreateFormatters();
|
|
}
|
|
|
|
public void rebuildUiParts()
|
|
{
|
|
KeepAliveService kas = KeepAliveService.getInstance();
|
|
if( kas != null ) {
|
|
kas.updateForegroundNotification();
|
|
}
|
|
}
|
|
|
|
public static String getCurrentLanguageName() {
|
|
return getString("LanguageName", R.string.LanguageName);
|
|
}
|
|
|
|
private String getStringInternal(String key, int res) {
|
|
String value = null;
|
|
try {
|
|
value = ApplicationLoader.applicationContext.getString(res);
|
|
} catch (Exception e) { }
|
|
if (value == null) {
|
|
value = "LOC_ERR:" + key;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
public static String getString(String key, int res) {
|
|
return getInstance().getStringInternal(key, res);
|
|
}
|
|
|
|
public static String formatString(String key, int res, Object... args) {
|
|
try {
|
|
String 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) {
|
|
|
|
return "LOC_ERR: " + key;
|
|
}
|
|
}
|
|
|
|
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) {
|
|
|
|
return "LOC_ERR: " + string;
|
|
}
|
|
}
|
|
|
|
public void onDeviceConfigurationChange(Configuration newConfig) {
|
|
if (changingConfiguration) {
|
|
return;
|
|
}
|
|
is24HourFormat = DateFormat.is24HourFormat(ApplicationLoader.applicationContext);
|
|
systemDefaultLocale = newConfig.locale;
|
|
if (languageOverride != null) {
|
|
LocaleInfo toSet = currentLocaleInfo;
|
|
currentLocaleInfo = null;
|
|
applyLanguage(toSet, false);
|
|
} 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;
|
|
}
|
|
}
|
|
rebuildUiParts();
|
|
}
|
|
|
|
public static String formatDateChat(long date) {
|
|
try {
|
|
Calendar rightNow = Calendar.getInstance();
|
|
int year = rightNow.get(Calendar.YEAR);
|
|
|
|
rightNow.setTimeInMillis(date * 1000);
|
|
int dateYear = rightNow.get(Calendar.YEAR);
|
|
|
|
if (year == dateYear) {
|
|
return getInstance().chatDate.format(date * 1000);
|
|
}
|
|
return getInstance().chatFullDate.format(date * 1000);
|
|
} catch (Exception e) {
|
|
|
|
}
|
|
return "LOC_ERR: formatDateChat";
|
|
}
|
|
|
|
private FastDateFormat createFormatter(Locale locale, String format, String defaultFormat) {
|
|
if (format == null || format.length() == 0) {
|
|
format = defaultFormat;
|
|
}
|
|
FastDateFormat formatter;
|
|
try {
|
|
formatter = FastDateFormat.getInstance(format, locale);
|
|
} catch (Exception e) {
|
|
format = defaultFormat;
|
|
formatter = FastDateFormat.getInstance(format, locale);
|
|
}
|
|
return formatter;
|
|
}
|
|
|
|
private void recreateFormatters() {
|
|
Locale locale = currentLocale;
|
|
if (locale == null) {
|
|
locale = Locale.getDefault();
|
|
}
|
|
String lang = locale.getLanguage();
|
|
if (lang == null) {
|
|
lang = "en";
|
|
}
|
|
isRTL = lang.toLowerCase().equals("ar");
|
|
nameDisplayOrder = lang.toLowerCase().equals("ko") ? 2 : 1;
|
|
|
|
formatterMonth = createFormatter(locale, getStringInternal("formatterMonth", R.string.formatterMonth), "dd MMM");
|
|
formatterYear = createFormatter(locale, getStringInternal("formatterYear", R.string.formatterYear), "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");
|
|
formatterMonthYear = createFormatter(locale, getStringInternal("formatterMonthYear", R.string.formatterMonthYear), "MMMM yyyy");
|
|
formatterDay = createFormatter(lang.toLowerCase().equals("ar") || lang.toLowerCase().equals("ko") ? locale : Locale.US, is24HourFormat ? getStringInternal("formatterDay24H", R.string.formatterDay24H) : getStringInternal("formatterDay12H", R.string.formatterDay12H), is24HourFormat ? "HH:mm" : "h:mm a");
|
|
}
|
|
|
|
public static String stringForMessageListDate(long date) {
|
|
try {
|
|
Calendar rightNow = Calendar.getInstance();
|
|
int day = rightNow.get(Calendar.DAY_OF_YEAR);
|
|
int year = rightNow.get(Calendar.YEAR);
|
|
rightNow.setTimeInMillis(date * 1000);
|
|
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
|
|
int dateYear = rightNow.get(Calendar.YEAR);
|
|
|
|
if (year != dateYear) {
|
|
return getInstance().formatterYear.format(new Date(date * 1000));
|
|
} else {
|
|
int dayDiff = dateDay - day;
|
|
if(dayDiff == 0 || dayDiff == -1 && (int)(System.currentTimeMillis() / 1000) - date < 60 * 60 * 8) {
|
|
return getInstance().formatterDay.format(new Date(date * 1000));
|
|
} else if(dayDiff > -7 && dayDiff <= -1) {
|
|
return getInstance().formatterWeek.format(new Date(date * 1000));
|
|
} else {
|
|
return getInstance().formatterMonth.format(new Date(date * 1000));
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
|
|
}
|
|
return "LOC_ERR";
|
|
}
|
|
}
|