Simplify locale override (#5509)
This commit is contained in:
parent
49cdcc644c
commit
37d30eb887
6 changed files with 45 additions and 110 deletions
|
@ -7,7 +7,6 @@ import android.content.BroadcastReceiver
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.webkit.WebView
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
|
@ -28,7 +27,6 @@ import eu.kanade.tachiyomi.data.notification.Notifications
|
|||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||
import eu.kanade.tachiyomi.util.system.notification
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
@ -68,8 +66,6 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
|
|||
setupAcra()
|
||||
setupNotificationChannels()
|
||||
|
||||
LocaleHelper.updateConfiguration(this, resources.configuration)
|
||||
|
||||
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
|
||||
|
||||
// Show notification to disable Incognito Mode when it's enabled
|
||||
|
@ -106,11 +102,6 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
|
|||
MultiDex.install(this)
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
LocaleHelper.updateConfiguration(this, newConfig, true)
|
||||
}
|
||||
|
||||
override fun newImageLoader(): ImageLoader {
|
||||
return ImageLoader.Builder(this).apply {
|
||||
componentRegistry {
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.os.Bundle
|
|||
import androidx.viewbinding.ViewBinding
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||
import nucleus.view.NucleusAppCompatActivity
|
||||
|
||||
abstract class BaseRxActivity<VB : ViewBinding, P : BasePresenter<*>> : NucleusAppCompatActivity<P>() {
|
||||
|
@ -14,11 +13,6 @@ abstract class BaseRxActivity<VB : ViewBinding, P : BasePresenter<*>> : NucleusA
|
|||
|
||||
lateinit var binding: VB
|
||||
|
||||
init {
|
||||
@Suppress("LeakingThis")
|
||||
LocaleHelper.updateConfiguration(this)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package eu.kanade.tachiyomi.ui.base.activity
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
|
@ -8,6 +9,7 @@ import eu.kanade.tachiyomi.R
|
|||
import eu.kanade.tachiyomi.data.preference.PreferenceValues
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||
import eu.kanade.tachiyomi.util.view.setSecureScreen
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import uy.kohesive.injekt.Injekt
|
||||
|
@ -18,6 +20,10 @@ abstract class BaseThemedActivity : AppCompatActivity() {
|
|||
|
||||
val preferences: PreferencesHelper by injectLazy()
|
||||
|
||||
override fun attachBaseContext(newBase: Context) {
|
||||
super.attachBaseContext(LocaleHelper.createLocaleWrapper(newBase))
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
applyThemePreferences(preferences)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package eu.kanade.tachiyomi.ui.base.activity
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
||||
|
@ -12,9 +13,8 @@ abstract class BaseViewBindingActivity<VB : ViewBinding> : BaseThemedActivity()
|
|||
@Suppress("LeakingThis")
|
||||
private val secureActivityDelegate = SecureActivityDelegate(this)
|
||||
|
||||
init {
|
||||
@Suppress("LeakingThis")
|
||||
LocaleHelper.updateConfiguration(this)
|
||||
override fun attachBaseContext(newBase: Context) {
|
||||
super.attachBaseContext(LocaleHelper.createLocaleWrapper(newBase))
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
|
@ -232,11 +232,7 @@ class SettingsGeneralController : SettingsController() {
|
|||
summary = "%s"
|
||||
|
||||
onChange { newValue ->
|
||||
val activity = activity ?: return@onChange false
|
||||
val app = activity.application
|
||||
LocaleHelper.changeLocale(newValue.toString())
|
||||
LocaleHelper.updateConfiguration(app, app.resources.configuration)
|
||||
activity.recreate()
|
||||
activity?.recreate()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package eu.kanade.tachiyomi.util.system
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.view.ContextThemeWrapper
|
||||
import androidx.core.os.ConfigurationCompat
|
||||
import android.os.LocaleList
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.ui.browse.source.SourcePresenter
|
||||
|
@ -15,36 +15,10 @@ import java.util.Locale
|
|||
/**
|
||||
* Utility class to change the application's language in runtime.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
object LocaleHelper {
|
||||
|
||||
private val preferences: PreferencesHelper by injectLazy()
|
||||
|
||||
private var systemLocale: Locale? = null
|
||||
|
||||
/**
|
||||
* The application's locale. When it's null, the system locale is used.
|
||||
*/
|
||||
private var appLocale = getLocaleFromString(preferences.lang().get())
|
||||
|
||||
/**
|
||||
* The currently applied locale. Used to avoid losing the selected language after a non locale
|
||||
* configuration change to the application.
|
||||
*/
|
||||
private var currentLocale: Locale? = null
|
||||
|
||||
/**
|
||||
* Returns the locale for the value stored in preferences, or null if it's system language.
|
||||
*
|
||||
* @param pref the string value stored in preferences.
|
||||
*/
|
||||
fun getLocaleFromString(pref: String?): Locale? {
|
||||
if (pref.isNullOrEmpty()) {
|
||||
return null
|
||||
}
|
||||
return getLocale(pref)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Display name of a string language code
|
||||
*/
|
||||
|
@ -60,18 +34,35 @@ object LocaleHelper {
|
|||
|
||||
/**
|
||||
* Returns Display name of a string language code
|
||||
*
|
||||
* @param lang empty for system language
|
||||
*/
|
||||
fun getDisplayName(lang: String?): String {
|
||||
return when (lang) {
|
||||
null -> ""
|
||||
"" -> {
|
||||
systemLocale!!.getDisplayName(systemLocale).capitalize()
|
||||
}
|
||||
else -> {
|
||||
val locale = getLocale(lang)
|
||||
locale.getDisplayName(locale).capitalize()
|
||||
}
|
||||
if (lang == null) {
|
||||
return ""
|
||||
}
|
||||
|
||||
val locale = if (lang.isEmpty()) {
|
||||
LocaleListCompat.getAdjustedDefault()[0]
|
||||
} else {
|
||||
getLocale(lang)
|
||||
}
|
||||
return locale.getDisplayName(locale).replaceFirstChar { it.uppercase(locale) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ContextWrapper using selected Locale
|
||||
*/
|
||||
fun createLocaleWrapper(context: Context): ContextWrapper {
|
||||
val appLocale = getLocaleFromString(preferences.lang().get())
|
||||
val newConfiguration = Configuration(context.resources.configuration)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val localeList = LocaleList(appLocale)
|
||||
newConfiguration.setLocales(localeList)
|
||||
} else {
|
||||
newConfiguration.setLocale(appLocale)
|
||||
}
|
||||
return ContextWrapper(context.createConfigurationContext(newConfiguration))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,57 +78,14 @@ object LocaleHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Changes the application's locale with a new preference.
|
||||
* Returns the locale for the value stored in preferences, defaults to main system language.
|
||||
*
|
||||
* @param pref the new value stored in preferences.
|
||||
* @param pref the string value stored in preferences.
|
||||
*/
|
||||
fun changeLocale(pref: String) {
|
||||
appLocale = getLocaleFromString(pref)
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the app's language to an activity.
|
||||
*/
|
||||
fun updateConfiguration(wrapper: ContextThemeWrapper) {
|
||||
if (appLocale != null) {
|
||||
val config = Configuration(preferences.context.resources.configuration)
|
||||
config.setLocale(appLocale)
|
||||
wrapper.applyOverrideConfiguration(config)
|
||||
private fun getLocaleFromString(pref: String?): Locale {
|
||||
if (pref.isNullOrEmpty()) {
|
||||
return LocaleListCompat.getDefault()[0]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the app's language to the application.
|
||||
*/
|
||||
fun updateConfiguration(app: Application, config: Configuration, configChange: Boolean = false) {
|
||||
if (systemLocale == null) {
|
||||
systemLocale = ConfigurationCompat.getLocales(config)[0]
|
||||
}
|
||||
if (configChange) {
|
||||
val configLocale = ConfigurationCompat.getLocales(config)[0]
|
||||
if (currentLocale == configLocale) {
|
||||
return
|
||||
}
|
||||
systemLocale = configLocale
|
||||
}
|
||||
currentLocale = appLocale ?: systemLocale ?: Locale.getDefault()
|
||||
val newConfig = updateConfigLocale(config, currentLocale!!)
|
||||
val resources = app.resources
|
||||
resources.updateConfiguration(newConfig, resources.displayMetrics)
|
||||
|
||||
Locale.setDefault(currentLocale!!)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new configuration with the given locale applied.
|
||||
*/
|
||||
private fun updateConfigLocale(config: Configuration, locale: Locale): Configuration {
|
||||
val newConfig = Configuration(config)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
newConfig.locale = locale
|
||||
} else {
|
||||
newConfig.setLocale(locale)
|
||||
}
|
||||
return newConfig
|
||||
return getLocale(pref)
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue