diff --git a/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java b/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java index c1d4cbc1..1b017548 100644 --- a/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java +++ b/app/src/main/java/com/keylesspalace/tusky/BaseActivity.java @@ -16,6 +16,7 @@ package com.keylesspalace.tusky; import android.app.ActivityManager; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; @@ -99,6 +100,11 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab callList = new ArrayList<>(); } + @Override + protected void attachBaseContext(Context base) { + super.attachBaseContext(TuskyApplication.localeManager.setLocale(base)); + } + protected boolean requiresLogin() { return true; } diff --git a/app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.kt b/app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.kt index 305de956..5d7cdf4f 100644 --- a/app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.kt @@ -125,16 +125,9 @@ class PreferencesActivity : BaseActivity(), SharedPreferences.OnSharedPreference val theme = sharedPreferences.getNonNullString("appTheme", ThemeUtils.APP_THEME_DEFAULT) Log.d("activeTheme", theme) ThemeUtils().setAppNightMode(theme, this) - restartActivitiesOnExit = true - // recreate() could be used instead, but it doesn't have an animation B). - intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK - val savedInstanceState = Bundle() - saveInstanceState(savedInstanceState) - intent.putExtras(savedInstanceState) - startActivityWithSlideInAnimation(intent) - finish() - overridePendingTransition(R.anim.fade_in, R.anim.fade_out) + restartActivitiesOnExit = true + this.restartCurrentActivity() // MODE_NIGHT_FOLLOW_SYSTEM workaround part 2 :/ when(theme){ @@ -143,7 +136,6 @@ class PreferencesActivity : BaseActivity(), SharedPreferences.OnSharedPreference } } //workaround end - } "statusTextSize" -> { restartActivitiesOnExit = true @@ -151,11 +143,24 @@ class PreferencesActivity : BaseActivity(), SharedPreferences.OnSharedPreference "absoluteTimeView" -> { restartActivitiesOnExit = true } + "language" -> { + restartActivitiesOnExit = true + this.restartCurrentActivity() + } } eventHub.dispatch(PreferenceChangedEvent(key)) } + private fun restartCurrentActivity() { + intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK + val savedInstanceState = Bundle() + saveInstanceState(savedInstanceState) + intent.putExtras(savedInstanceState) + startActivityWithSlideInAnimation(intent) + finish() + overridePendingTransition(R.anim.fade_in, R.anim.fade_out) + } override fun onBackPressed() { /* Switching themes won't actually change the theme of activities on the back stack. diff --git a/app/src/main/java/com/keylesspalace/tusky/TuskyApplication.java b/app/src/main/java/com/keylesspalace/tusky/TuskyApplication.java index ce3dde8d..80778aa0 100644 --- a/app/src/main/java/com/keylesspalace/tusky/TuskyApplication.java +++ b/app/src/main/java/com/keylesspalace/tusky/TuskyApplication.java @@ -20,7 +20,10 @@ import android.app.Application; import android.app.Service; import androidx.room.Room; import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.res.Configuration; import android.preference.PreferenceManager; +import android.util.Log; import androidx.emoji.text.EmojiCompat; import com.evernote.android.job.JobManager; @@ -29,6 +32,7 @@ import com.keylesspalace.tusky.db.AccountManager; import com.keylesspalace.tusky.db.AppDatabase; import com.keylesspalace.tusky.di.AppInjector; import com.keylesspalace.tusky.util.EmojiCompatFont; +import com.keylesspalace.tusky.util.LocaleManager; import com.keylesspalace.tusky.util.NotificationPullJobCreator; import com.squareup.picasso.Picasso; @@ -62,6 +66,10 @@ public class TuskyApplication extends Application implements HasActivityInjector private ServiceLocator serviceLocator; + public static LocaleManager localeManager; + + private final String TAG = "TuskyApplication"; + @Override public void onCreate() { super.onCreate(); @@ -103,6 +111,18 @@ public class TuskyApplication extends Application implements HasActivityInjector Security.insertProviderAt(Conscrypt.newProvider(), 1); } + @Override + protected void attachBaseContext(Context base) { + localeManager = new LocaleManager(base); + super.attachBaseContext(localeManager.setLocale(base)); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + localeManager.setLocale(this); + } + /** * This method will load the EmojiCompat font which has been selected. * If this font does not work or if the user hasn't selected one (yet), it will use a @@ -157,4 +177,4 @@ public class TuskyApplication extends Application implements HasActivityInjector public interface ServiceLocator { T get(Class clazz); } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/keylesspalace/tusky/fragment/preference/PreferencesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/fragment/preference/PreferencesFragment.kt index f3aa5bce..20e0edb0 100644 --- a/app/src/main/java/com/keylesspalace/tusky/fragment/preference/PreferencesFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/fragment/preference/PreferencesFragment.kt @@ -62,6 +62,8 @@ class PreferencesFragment : PreferenceFragmentCompat() { true } + val languagePreference: Preference = findPreference("language") + languagePreference.icon = IconicsDrawable(languagePreference.context, GoogleMaterial.Icon.gmd_translate).sizePx(iconSize).color(ThemeUtils.getColor(languagePreference.context, R.attr.toolbar_icon_tint)) } override fun onResume() { @@ -75,22 +77,22 @@ class PreferencesFragment : PreferenceFragmentCompat() { val sharedPreferences = preferenceManager.sharedPreferences - val httpProxyEnabled = sharedPreferences.getBoolean("httpProxyEnabled", false) + val httpProxyEnabled = sharedPreferences.getBoolean("httpProxyEnabled", false) - val httpServer = sharedPreferences.getNonNullString("httpProxyServer", "") + val httpServer = sharedPreferences.getNonNullString("httpProxyServer", "") - try { - val httpPort = sharedPreferences.getNonNullString("httpProxyPort", "-1").toInt() + try { + val httpPort = sharedPreferences.getNonNullString("httpProxyPort", "-1").toInt() - if (httpProxyEnabled && httpServer.isNotBlank() && httpPort > 0 && httpPort < 65535) { - httpProxyPref.summary = "$httpServer:$httpPort" - return - } - } catch (e: NumberFormatException) { - // user has entered wrong port, fall back to empty summary + if (httpProxyEnabled && httpServer.isNotBlank() && httpPort > 0 && httpPort < 65535) { + httpProxyPref.summary = "$httpServer:$httpPort" + return } + } catch (e: NumberFormatException) { + // user has entered wrong port, fall back to empty summary + } - httpProxyPref.summary = "" + httpProxyPref.summary = "" } diff --git a/app/src/main/java/com/keylesspalace/tusky/util/LocaleManager.kt b/app/src/main/java/com/keylesspalace/tusky/util/LocaleManager.kt new file mode 100644 index 00000000..19f42f50 --- /dev/null +++ b/app/src/main/java/com/keylesspalace/tusky/util/LocaleManager.kt @@ -0,0 +1,46 @@ +/* Copyright 2019 Mélanie Chauvel (ariasuni) + * + * This file is a part of Tusky. + * + * 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. + * + * Tusky 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 Tusky; if not, + * see . */ + +package com.keylesspalace.tusky.util + +import android.content.Context +import android.content.SharedPreferences +import android.content.res.Configuration +import android.content.res.Resources +import android.preference.PreferenceManager + +import java.util.Locale + +import com.keylesspalace.tusky.util.getNonNullString + + +class LocaleManager(context: Context) { + + private var prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) + + fun setLocale(context: Context): Context { + val language = prefs.getNonNullString("language", "default") + if (language.equals("default")) { + return context; + } + val locale = Locale.forLanguageTag(language) + Locale.setDefault(locale) + + val res = context.getResources() + val config = Configuration(res.getConfiguration()); + config.setLocale(locale) + return context.createConfigurationContext(config) + } +} diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 97847dca..bb327f29 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -31,4 +31,65 @@ auto_system + + @string/system_default + Català + Cymraeg + Deutsch + English + Español + Euskara + Français + Italiano + Magyar + Nederlands + Occitan + Polski + Português (Brasil) + Svenska + Türkçe + Русский + العَرَبِيَّة‎ + فارسی + தமிழ் + 한국어 + 中文(台灣) + 中文(新加坡) + 中文(澳門) + 中文(简体) + 中文(香港) + 日本語 + + + + default + ca + cy + de + en + es + eu + fr + it + hu + nl + oc + pl + pt-BR + sv + tr + ru + ar + fa + ta + ko + zh-TW + zh-SG + zh-MO + zh-CN + zh-HK + ja + + + Language diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2e74e184..7711b743 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -211,6 +211,7 @@ Browser Use Chrome Custom Tabs Hide compose button while scrolling + Language Timeline filtering Tabs Show boosts diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 96d4dba3..8e4a92ad 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -21,6 +21,14 @@ android:icon="@drawable/ic_emoji_24dp" android:title="@string/emoji_style" /> + +