Lazy load available languages

This commit is contained in:
Benoit Marty 2020-05-14 22:32:47 +02:00
parent a00ddca188
commit 538bda329e
5 changed files with 89 additions and 48 deletions

View File

@ -24,7 +24,9 @@ import androidx.preference.PreferenceManager
import im.vector.riotx.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.util.Locale
@ -40,9 +42,9 @@ object VectorLocale {
private val defaultLocale = Locale("en", "US")
/**
* The supported application languages
* The cache of supported application languages
*/
val supportedLocales = mutableListOf<Locale>()
private val supportedLocales = mutableListOf<Locale>()
/**
* Provides the current application locale
@ -75,11 +77,6 @@ object VectorLocale {
saveApplicationLocale(applicationLocale)
}
// init the known locales in background
GlobalScope.launch(Dispatchers.IO) {
initApplicationLocales(context)
}
}
/**
@ -167,11 +164,9 @@ object VectorLocale {
}
/**
* Provides the supported application locales list
*
* @param context the context
* Init the supported application locales list
*/
private fun initApplicationLocales(context: Context) {
private fun initApplicationLocales() {
val knownLocalesSet = HashSet<Triple<String, String, String>>()
try {
@ -262,4 +257,20 @@ object VectorLocale {
append("]")
}
}
fun loadLocales(listener: Listener): Job {
return GlobalScope.launch(Dispatchers.Main) {
if (supportedLocales.isEmpty()) {
// init the known locales in background
withContext(Dispatchers.IO) {
initApplicationLocales()
}
}
listener.onLoaded(supportedLocales)
}
}
interface Listener {
fun onLoaded(locales: List<Locale>)
}
}

View File

@ -17,7 +17,10 @@
package im.vector.riotx.features.settings.locale
import com.airbnb.epoxy.TypedEpoxyController
import com.airbnb.mvrx.Incomplete
import com.airbnb.mvrx.Success
import im.vector.riotx.R
import im.vector.riotx.core.epoxy.loadingItem
import im.vector.riotx.core.epoxy.noResultItem
import im.vector.riotx.core.epoxy.profiles.profileSectionItem
import im.vector.riotx.core.resources.StringProvider
@ -37,40 +40,49 @@ class LocalePickerController @Inject constructor(
override fun buildModels(data: LocalePickerViewState?) {
val list = data?.locales ?: return
if (list.isEmpty()) {
noResultItem {
id("noResult")
text(stringProvider.getString(R.string.no_result_placeholder))
profileSectionItem {
id("currentTitle")
title(stringProvider.getString(R.string.choose_locale_current_locale_title))
}
localeItem {
id(data.currentLocale.toString())
title(VectorLocale.localeToLocalisedString(data.currentLocale).capitalize(data.currentLocale))
if (vectorPreferences.developerMode()) {
subtitle(VectorLocale.localeToLocalisedStringInfo(data.currentLocale))
}
} else {
profileSectionItem {
id("currentTitle")
title(stringProvider.getString(R.string.choose_locale_current_locale_title))
}
localeItem {
id(data.currentLocale.toString())
title(VectorLocale.localeToLocalisedString(data.currentLocale).capitalize(data.currentLocale))
if (vectorPreferences.developerMode()) {
subtitle(VectorLocale.localeToLocalisedStringInfo(data.currentLocale))
clickListener { listener?.onUseCurrentClicked() }
}
profileSectionItem {
id("otherTitle")
title(stringProvider.getString(R.string.choose_locale_other_locales_title))
}
when (list) {
is Incomplete -> {
loadingItem {
id("loading")
loadingText(stringProvider.getString(R.string.choose_locale_loading_locales))
}
clickListener { listener?.onUseCurrentClicked() }
}
profileSectionItem {
id("otherTitle")
title(stringProvider.getString(R.string.choose_locale_other_locales_title))
}
list
.filter { it.toString() != data.currentLocale.toString() }
.forEach {
localeItem {
id(it.toString())
title(VectorLocale.localeToLocalisedString(it).capitalize(it))
if (vectorPreferences.developerMode()) {
subtitle(VectorLocale.localeToLocalisedStringInfo(it))
}
clickListener { listener?.onLocaleClicked(it) }
}
is Success ->
if (list().isEmpty()) {
noResultItem {
id("noResult")
text(stringProvider.getString(R.string.no_result_placeholder))
}
} else {
list()
.filter { it.toString() != data.currentLocale.toString() }
.forEach {
localeItem {
id(it.toString())
title(VectorLocale.localeToLocalisedString(it).capitalize(it))
if (vectorPreferences.developerMode()) {
subtitle(VectorLocale.localeToLocalisedStringInfo(it))
}
clickListener { listener?.onLocaleClicked(it) }
}
}
}
}
}

View File

@ -19,28 +19,30 @@ package im.vector.riotx.features.settings.locale
import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.ViewModelContext
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.riotx.core.extensions.exhaustive
import im.vector.riotx.core.platform.VectorViewModel
import im.vector.riotx.features.settings.VectorLocale
import kotlinx.coroutines.Job
import java.util.Locale
class LocalePickerViewModel @AssistedInject constructor(
@Assisted initialState: LocalePickerViewState
) : VectorViewModel<LocalePickerViewState, LocalePickerAction, LocalePickerViewEvents>(initialState) {
) : VectorViewModel<LocalePickerViewState, LocalePickerAction, LocalePickerViewEvents>(initialState),
VectorLocale.Listener {
@AssistedInject.Factory
interface Factory {
fun create(initialState: LocalePickerViewState): LocalePickerViewModel
}
private var loadingJob: Job? = null
init {
setState {
copy(
locales = VectorLocale.supportedLocales
)
}
loadingJob = VectorLocale.loadLocales(this)
}
companion object : MvRxViewModelFactory<LocalePickerViewModel, LocalePickerViewState> {
@ -65,4 +67,17 @@ class LocalePickerViewModel @AssistedInject constructor(
VectorLocale.saveApplicationLocale(action.locale)
_viewEvents.post(LocalePickerViewEvents.RestartActivity)
}
override fun onLoaded(locales: List<Locale>) {
setState {
copy(
locales = Success(locales)
)
}
}
override fun onCleared() {
super.onCleared()
loadingJob?.cancel()
}
}

View File

@ -16,11 +16,13 @@
package im.vector.riotx.features.settings.locale
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MvRxState
import com.airbnb.mvrx.Uninitialized
import im.vector.riotx.features.settings.VectorLocale
import java.util.Locale
data class LocalePickerViewState(
val currentLocale: Locale = VectorLocale.applicationLocale,
val locales: List<Locale> = emptyList()
val locales: Async<List<Locale>> = Uninitialized
) : MvRxState

View File

@ -2395,5 +2395,6 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming
<string name="choose_locale_current_locale_title">Current language</string>
<string name="choose_locale_other_locales_title">Other available languages</string>
<string name="choose_locale_loading_locales">Loading available languages…</string>
</resources>