mihon/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt

121 lines
3.6 KiB
Kotlin

package eu.kanade.tachiyomi.util
import android.app.Application
import android.content.res.Configuration
import android.os.Build
import android.os.LocaleList
import android.view.ContextThemeWrapper
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import uy.kohesive.injekt.injectLazy
import java.util.*
/**
* Utility class to change the application's language in runtime.
*/
@Suppress("DEPRECATION")
object LocaleHelper {
/**
* Preferences helper.
*/
private val preferences: PreferencesHelper by injectLazy()
/**
* The system's locale.
*/
private var systemLocale: Locale? = null
/**
* The application's locale. When it's null, the system locale is used.
*/
private var appLocale = getLocaleFromString(preferences.lang())
/**
* 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
}
val parts = pref.split("_", "-")
val lang = parts[0]
val country = parts.getOrNull(1) ?: ""
return Locale(lang, country)
}
/**
* Changes the application's locale with a new preference.
*
* @param pref the new value stored in preferences.
*/
fun changeLocale(pref: String) {
appLocale = getLocaleFromString(pref)
}
/**
* Updates the app's language to an activity.
*/
fun updateConfiguration(wrapper: ContextThemeWrapper) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && appLocale != null) {
val config = Configuration(preferences.context.resources.configuration)
config.setLocale(appLocale)
wrapper.applyOverrideConfiguration(config)
}
}
/**
* Updates the app's language to the application.
*/
fun updateConfiguration(app: Application, config: Configuration, configChange: Boolean = false) {
if (systemLocale == null) {
systemLocale = getConfigLocale(config)
}
if (configChange) {
val configLocale = getConfigLocale(config)
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 the locale applied in the given configuration.
*/
private fun getConfigLocale(config: Configuration): Locale {
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
config.locale
} else {
config.locales[0]
}
}
/**
* 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.locales = LocaleList(locale)
}
return newConfig
}
}