Fix `StaticFieldLeak` issue (context).

Make VectorLocal an injectable class.
This commit is contained in:
Benoit Marty 2022-09-16 11:41:41 +02:00 committed by Benoit Marty
parent 7e8a39e6de
commit d8436874e2
18 changed files with 78 additions and 47 deletions

View File

@ -80,6 +80,7 @@
<issue id="KotlinPropertyAccess" severity="error" /> <issue id="KotlinPropertyAccess" severity="error" />
<issue id="DefaultLocale" severity="error" /> <issue id="DefaultLocale" severity="error" />
<issue id="CheckResult" severity="error" /> <issue id="CheckResult" severity="error" />
<issue id="StaticFieldLeak" severity="error" />
<issue id="InvalidPackage"> <issue id="InvalidPackage">
<!-- Ignore error from HtmlCompressor lib --> <!-- Ignore error from HtmlCompressor lib -->

View File

@ -109,6 +109,7 @@ class VectorApplication :
@Inject lateinit var fcmHelper: FcmHelper @Inject lateinit var fcmHelper: FcmHelper
@Inject lateinit var buildMeta: BuildMeta @Inject lateinit var buildMeta: BuildMeta
@Inject lateinit var leakDetector: LeakDetector @Inject lateinit var leakDetector: LeakDetector
@Inject lateinit var vectorLocale: VectorLocale
// font thread handler // font thread handler
private var fontThreadHandler: Handler? = null private var fontThreadHandler: Handler? = null
@ -159,7 +160,7 @@ class VectorApplication :
R.array.com_google_android_gms_fonts_certs R.array.com_google_android_gms_fonts_certs
) )
FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler()) FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler())
VectorLocale.init(this, buildMeta) vectorLocale.init()
ThemeUtils.init(this) ThemeUtils.init(this)
vectorConfiguration.applyToApplicationContext() vectorConfiguration.applyToApplicationContext()

View File

@ -84,6 +84,7 @@ import im.vector.app.features.rageshake.RageShake
import im.vector.app.features.session.SessionListener import im.vector.app.features.session.SessionListener
import im.vector.app.features.settings.FontScalePreferences import im.vector.app.features.settings.FontScalePreferences
import im.vector.app.features.settings.FontScalePreferencesImpl import im.vector.app.features.settings.FontScalePreferencesImpl
import im.vector.app.features.settings.VectorLocale
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.themes.ActivityOtherThemes import im.vector.app.features.themes.ActivityOtherThemes
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
@ -155,6 +156,7 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
@Inject lateinit var rageShake: RageShake @Inject lateinit var rageShake: RageShake
@Inject lateinit var buildMeta: BuildMeta @Inject lateinit var buildMeta: BuildMeta
@Inject lateinit var fontScalePreferences: FontScalePreferences @Inject lateinit var fontScalePreferences: FontScalePreferences
@Inject lateinit var vectorLocale: VectorLocale
// For debug only // For debug only
@Inject lateinit var debugReceiver: DebugReceiver @Inject lateinit var debugReceiver: DebugReceiver
@ -177,7 +179,7 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
override fun attachBaseContext(base: Context) { override fun attachBaseContext(base: Context) {
val fontScalePreferences = FontScalePreferencesImpl(PreferenceManager.getDefaultSharedPreferences(base), AndroidSystemSettingsProvider(base)) val fontScalePreferences = FontScalePreferencesImpl(PreferenceManager.getDefaultSharedPreferences(base), AndroidSystemSettingsProvider(base))
val vectorConfiguration = VectorConfiguration(this, fontScalePreferences) val vectorConfiguration = VectorConfiguration(this, fontScalePreferences, vectorLocale)
super.attachBaseContext(vectorConfiguration.getLocalisedContext(base)) super.attachBaseContext(vectorConfiguration.getLocalisedContext(base))
} }

View File

@ -49,6 +49,7 @@ class JitsiService @Inject constructor(
private val themeProvider: ThemeProvider, private val themeProvider: ThemeProvider,
private val jitsiJWTFactory: JitsiJWTFactory, private val jitsiJWTFactory: JitsiJWTFactory,
private val clock: Clock, private val clock: Clock,
private val vectorLocale: VectorLocale,
) { ) {
companion object { companion object {
@ -163,7 +164,7 @@ class JitsiService @Inject constructor(
if (widgetSessionId.length > 8) { if (widgetSessionId.length > 8) {
widgetSessionId = widgetSessionId.substring(0, 7) widgetSessionId = widgetSessionId.substring(0, 7)
} }
roomId.substring(1, roomId.indexOf(":") - 1) + widgetSessionId.lowercase(VectorLocale.applicationLocale) roomId.substring(1, roomId.indexOf(":") - 1) + widgetSessionId.lowercase(vectorLocale.applicationLocale)
} }
} }

View File

@ -20,12 +20,15 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.addChildFragment import im.vector.app.core.extensions.addChildFragment
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.databinding.BottomSheetCallDialPadBinding import im.vector.app.databinding.BottomSheetCallDialPadBinding
import im.vector.app.features.settings.VectorLocale import im.vector.app.features.settings.VectorLocale
import javax.inject.Inject
@AndroidEntryPoint
class CallDialPadBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetCallDialPadBinding>() { class CallDialPadBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetCallDialPadBinding>() {
companion object { companion object {
@ -41,6 +44,8 @@ class CallDialPadBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetCa
} }
} }
@Inject lateinit var vectorLocale: VectorLocale
override val showExpanded = true override val showExpanded = true
var callback: DialPadFragment.Callback? = null var callback: DialPadFragment.Callback? = null
@ -62,7 +67,7 @@ class CallDialPadBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetCa
putBoolean(DialPadFragment.EXTRA_ENABLE_DELETE, showActions) putBoolean(DialPadFragment.EXTRA_ENABLE_DELETE, showActions)
putBoolean(DialPadFragment.EXTRA_ENABLE_OK, showActions) putBoolean(DialPadFragment.EXTRA_ENABLE_OK, showActions)
putBoolean(DialPadFragment.EXTRA_CURSOR_VISIBLE, false) putBoolean(DialPadFragment.EXTRA_CURSOR_VISIBLE, false)
putString(DialPadFragment.EXTRA_REGION_CODE, VectorLocale.applicationLocale.country) putString(DialPadFragment.EXTRA_REGION_CODE, vectorLocale.applicationLocale.country)
} }
callback = DialPadFragmentCallbackWrapper(this@CallDialPadBottomSheet.callback) callback = DialPadFragmentCallbackWrapper(this@CallDialPadBottomSheet.callback)
}.also { }.also {

View File

@ -78,7 +78,7 @@ class PstnDialActivity : SimpleFragmentActivity() {
arguments = Bundle().apply { arguments = Bundle().apply {
putBoolean(DialPadFragment.EXTRA_ENABLE_DELETE, true) putBoolean(DialPadFragment.EXTRA_ENABLE_DELETE, true)
putBoolean(DialPadFragment.EXTRA_ENABLE_OK, true) putBoolean(DialPadFragment.EXTRA_ENABLE_OK, true)
putString(DialPadFragment.EXTRA_REGION_CODE, VectorLocale.applicationLocale.country) putString(DialPadFragment.EXTRA_REGION_CODE, vectorLocale.applicationLocale.country)
} }
callback = object : DialPadFragment.Callback { callback = object : DialPadFragment.Callback {
override fun onOkClicked(formatted: String?, raw: String?) { override fun onOkClicked(formatted: String?, raw: String?) {

View File

@ -59,7 +59,7 @@ class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>() {
} }
} }
sectionsPagerAdapter = CallTransferPagerAdapter(this) sectionsPagerAdapter = CallTransferPagerAdapter(this, vectorLocale)
views.callTransferViewPager.adapter = sectionsPagerAdapter views.callTransferViewPager.adapter = sectionsPagerAdapter
TabLayoutMediator(views.callTransferTabLayout, views.callTransferViewPager) { tab, position -> TabLayoutMediator(views.callTransferTabLayout, views.callTransferViewPager) { tab, position ->

View File

@ -27,7 +27,8 @@ import im.vector.app.features.userdirectory.UserListFragment
import im.vector.app.features.userdirectory.UserListFragmentArgs import im.vector.app.features.userdirectory.UserListFragmentArgs
class CallTransferPagerAdapter( class CallTransferPagerAdapter(
private val fragmentActivity: FragmentActivity private val fragmentActivity: FragmentActivity,
private val vectorLocale: VectorLocale,
) : FragmentStateAdapter(fragmentActivity) { ) : FragmentStateAdapter(fragmentActivity) {
companion object { companion object {
@ -61,7 +62,7 @@ class CallTransferPagerAdapter(
arguments = Bundle().apply { arguments = Bundle().apply {
putBoolean(DialPadFragment.EXTRA_ENABLE_DELETE, true) putBoolean(DialPadFragment.EXTRA_ENABLE_DELETE, true)
putBoolean(DialPadFragment.EXTRA_ENABLE_OK, false) putBoolean(DialPadFragment.EXTRA_ENABLE_OK, false)
putString(DialPadFragment.EXTRA_REGION_CODE, VectorLocale.applicationLocale.country) putString(DialPadFragment.EXTRA_REGION_CODE, vectorLocale.applicationLocale.country)
} }
} }
} }

View File

@ -33,21 +33,22 @@ import javax.inject.Inject
*/ */
class VectorConfiguration @Inject constructor( class VectorConfiguration @Inject constructor(
private val context: Context, private val context: Context,
private val fontScalePreferences: FontScalePreferences private val fontScalePreferences: FontScalePreferences,
private val vectorLocale: VectorLocale,
) { ) {
fun onConfigurationChanged() { fun onConfigurationChanged() {
if (Locale.getDefault().toString() != VectorLocale.applicationLocale.toString()) { if (Locale.getDefault().toString() != vectorLocale.applicationLocale.toString()) {
Timber.v("## onConfigurationChanged(): the locale has been updated to ${Locale.getDefault()}") Timber.v("## onConfigurationChanged(): the locale has been updated to ${Locale.getDefault()}")
Timber.v("## onConfigurationChanged(): restore the expected value ${VectorLocale.applicationLocale}") Timber.v("## onConfigurationChanged(): restore the expected value ${vectorLocale.applicationLocale}")
Locale.setDefault(VectorLocale.applicationLocale) Locale.setDefault(vectorLocale.applicationLocale)
} }
// Night mode may have changed // Night mode may have changed
ThemeUtils.init(context) ThemeUtils.init(context)
} }
fun applyToApplicationContext() { fun applyToApplicationContext() {
val locale = VectorLocale.applicationLocale val locale = vectorLocale.applicationLocale
val fontScale = fontScalePreferences.getResolvedFontScaleValue() val fontScale = fontScalePreferences.getResolvedFontScaleValue()
Locale.setDefault(locale) Locale.setDefault(locale)
@ -67,7 +68,7 @@ class VectorConfiguration @Inject constructor(
*/ */
fun getLocalisedContext(context: Context): Context { fun getLocalisedContext(context: Context): Context {
try { try {
val locale = VectorLocale.applicationLocale val locale = vectorLocale.applicationLocale
// create new configuration passing old configuration from original Context // create new configuration passing old configuration from original Context
val configuration = Configuration(context.resources.configuration) val configuration = Configuration(context.resources.configuration)
@ -107,7 +108,7 @@ class VectorConfiguration @Inject constructor(
* @return the local status value * @return the local status value
*/ */
fun getHash(): String { fun getHash(): String {
return (VectorLocale.applicationLocale.toString() + return (vectorLocale.applicationLocale.toString() +
"_" + fontScalePreferences.getResolvedFontScaleValue().preferenceValue + "_" + fontScalePreferences.getResolvedFontScaleValue().preferenceValue +
"_" + ThemeUtils.getApplicationTheme(context)) "_" + ThemeUtils.getApplicationTheme(context))
} }

View File

@ -32,6 +32,7 @@ import im.vector.app.databinding.FragmentKeysBackupSetupStep2Binding
import im.vector.app.features.settings.VectorLocale import im.vector.app.features.settings.VectorLocale
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class KeysBackupSetupStep2Fragment : class KeysBackupSetupStep2Fragment :
@ -43,6 +44,8 @@ class KeysBackupSetupStep2Fragment :
private val zxcvbn = Zxcvbn() private val zxcvbn = Zxcvbn()
@Inject lateinit var vectorLocale: VectorLocale
private fun onPassphraseChanged() { private fun onPassphraseChanged() {
viewModel.passphrase.value = views.keysBackupSetupStep2PassphraseEnterEdittext.text.toString() viewModel.passphrase.value = views.keysBackupSetupStep2PassphraseEnterEdittext.text.toString()
viewModel.confirmPassphraseError.value = null viewModel.confirmPassphraseError.value = null
@ -78,12 +81,12 @@ class KeysBackupSetupStep2Fragment :
views.keysBackupSetupStep2PassphraseStrengthLevel.strength = score views.keysBackupSetupStep2PassphraseStrengthLevel.strength = score
if (score in 1..3) { if (score in 1..3) {
val warning = strength.feedback?.getWarning(VectorLocale.applicationLocale) val warning = strength.feedback?.getWarning(vectorLocale.applicationLocale)
if (warning != null) { if (warning != null) {
views.keysBackupSetupStep2PassphraseEnterTil.error = warning views.keysBackupSetupStep2PassphraseEnterTil.error = warning
} }
val suggestions = strength.feedback?.getSuggestions(VectorLocale.applicationLocale) val suggestions = strength.feedback?.getSuggestions(vectorLocale.applicationLocale)
if (suggestions != null) { if (suggestions != null) {
views.keysBackupSetupStep2PassphraseEnterTil.error = suggestions.firstOrNull() views.keysBackupSetupStep2PassphraseEnterTil.error = suggestions.firstOrNull()
} }

View File

@ -34,6 +34,7 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.android.widget.editorActionEvents import reactivecircus.flowbinding.android.widget.editorActionEvents
import reactivecircus.flowbinding.android.widget.textChanges import reactivecircus.flowbinding.android.widget.textChanges
import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class BootstrapEnterPassphraseFragment : class BootstrapEnterPassphraseFragment :
@ -43,6 +44,8 @@ class BootstrapEnterPassphraseFragment :
return FragmentBootstrapEnterPassphraseBinding.inflate(inflater, container, false) return FragmentBootstrapEnterPassphraseBinding.inflate(inflater, container, false)
} }
@Inject lateinit var vectorLocale: VectorLocale
val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel() val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -105,8 +108,8 @@ class BootstrapEnterPassphraseFragment :
views.ssssPassphraseSecurityProgress.strength = score views.ssssPassphraseSecurityProgress.strength = score
if (score in 1..3) { if (score in 1..3) {
val hint = val hint =
strength.feedback?.getWarning(VectorLocale.applicationLocale)?.takeIf { it.isNotBlank() } strength.feedback?.getWarning(vectorLocale.applicationLocale)?.takeIf { it.isNotBlank() }
?: strength.feedback?.getSuggestions(VectorLocale.applicationLocale)?.firstOrNull() ?: strength.feedback?.getSuggestions(vectorLocale.applicationLocale)?.firstOrNull()
if (hint != null && hint != views.ssssPassphraseEnterTil.error.toString()) { if (hint != null && hint != views.ssssPassphraseEnterTil.error.toString()) {
views.ssssPassphraseEnterTil.error = hint views.ssssPassphraseEnterTil.error = hint
} }

View File

@ -75,6 +75,7 @@ class HomeDetailFragment :
@Inject lateinit var callManager: WebRtcCallManager @Inject lateinit var callManager: WebRtcCallManager
@Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var vectorPreferences: VectorPreferences
@Inject lateinit var spaceStateHandler: SpaceStateHandler @Inject lateinit var spaceStateHandler: SpaceStateHandler
@Inject lateinit var vectorLocale: VectorLocale
private val viewModel: HomeDetailViewModel by fragmentViewModel() private val viewModel: HomeDetailViewModel by fragmentViewModel()
private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel() private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel()
@ -378,7 +379,7 @@ class HomeDetailFragment :
arguments = Bundle().apply { arguments = Bundle().apply {
putBoolean(DialPadFragment.EXTRA_ENABLE_DELETE, true) putBoolean(DialPadFragment.EXTRA_ENABLE_DELETE, true)
putBoolean(DialPadFragment.EXTRA_ENABLE_OK, true) putBoolean(DialPadFragment.EXTRA_ENABLE_OK, true)
putString(DialPadFragment.EXTRA_REGION_CODE, VectorLocale.applicationLocale.country) putString(DialPadFragment.EXTRA_REGION_CODE, vectorLocale.applicationLocale.country)
} }
applyCallback() applyCallback()
} }

View File

@ -80,6 +80,7 @@ class BugReporter @Inject constructor(
private val buildMeta: BuildMeta, private val buildMeta: BuildMeta,
private val processInfo: ProcessInfo, private val processInfo: ProcessInfo,
private val sdkIntProvider: BuildVersionSdkIntProvider, private val sdkIntProvider: BuildVersionSdkIntProvider,
private val vectorLocale: VectorLocale,
) { ) {
var inMultiWindowMode = false var inMultiWindowMode = false
@ -294,7 +295,7 @@ class BugReporter @Inject constructor(
Build.VERSION.INCREMENTAL + "-" + Build.VERSION.CODENAME Build.VERSION.INCREMENTAL + "-" + Build.VERSION.CODENAME
) )
.addFormDataPart("locale", Locale.getDefault().toString()) .addFormDataPart("locale", Locale.getDefault().toString())
.addFormDataPart("app_language", VectorLocale.applicationLocale.toString()) .addFormDataPart("app_language", vectorLocale.applicationLocale.toString())
.addFormDataPart("default_app_language", systemLocaleProvider.getSystemLocale().toString()) .addFormDataPart("default_app_language", systemLocaleProvider.getSystemLocale().toString())
.addFormDataPart("theme", ThemeUtils.getApplicationTheme(context)) .addFormDataPart("theme", ThemeUtils.getApplicationTheme(context))
.addFormDataPart("server_version", serverVersion) .addFormDataPart("server_version", serverVersion)

View File

@ -27,19 +27,27 @@ import kotlinx.coroutines.withContext
import timber.log.Timber import timber.log.Timber
import java.util.IllformedLocaleException import java.util.IllformedLocaleException
import java.util.Locale import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton
/** /**
* Object to manage the Locale choice of the user. * Object to manage the Locale choice of the user.
*/ */
object VectorLocale { @Singleton
private const val APPLICATION_LOCALE_COUNTRY_KEY = "APPLICATION_LOCALE_COUNTRY_KEY" class VectorLocale @Inject constructor(
private const val APPLICATION_LOCALE_VARIANT_KEY = "APPLICATION_LOCALE_VARIANT_KEY" private val context: Context,
private const val APPLICATION_LOCALE_LANGUAGE_KEY = "APPLICATION_LOCALE_LANGUAGE_KEY" private val buildMeta: BuildMeta,
private const val APPLICATION_LOCALE_SCRIPT_KEY = "APPLICATION_LOCALE_SCRIPT_KEY" ) {
companion object {
private const val APPLICATION_LOCALE_COUNTRY_KEY = "APPLICATION_LOCALE_COUNTRY_KEY"
private const val APPLICATION_LOCALE_VARIANT_KEY = "APPLICATION_LOCALE_VARIANT_KEY"
private const val APPLICATION_LOCALE_LANGUAGE_KEY = "APPLICATION_LOCALE_LANGUAGE_KEY"
private const val APPLICATION_LOCALE_SCRIPT_KEY = "APPLICATION_LOCALE_SCRIPT_KEY"
private const val ISO_15924_LATN = "Latn"
}
private val defaultLocale = Locale("en", "US") private val defaultLocale = Locale("en", "US")
private const val ISO_15924_LATN = "Latn"
/** /**
* The cache of supported application languages. * The cache of supported application languages.
@ -52,15 +60,10 @@ object VectorLocale {
var applicationLocale = defaultLocale var applicationLocale = defaultLocale
private set private set
private lateinit var context: Context
private lateinit var buildMeta: BuildMeta
/** /**
* Init this object. * Init this singleton.
*/ */
fun init(context: Context, buildMeta: BuildMeta) { fun init() {
this.context = context
this.buildMeta = buildMeta
val preferences = DefaultSharedPreferences.getInstance(context) val preferences = DefaultSharedPreferences.getInstance(context)
if (preferences.contains(APPLICATION_LOCALE_LANGUAGE_KEY)) { if (preferences.contains(APPLICATION_LOCALE_LANGUAGE_KEY)) {

View File

@ -46,6 +46,7 @@ class VectorSettingsPreferencesFragment :
@Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var vectorPreferences: VectorPreferences
@Inject lateinit var fontScalePreferences: FontScalePreferences @Inject lateinit var fontScalePreferences: FontScalePreferences
@Inject lateinit var vectorFeatures: VectorFeatures @Inject lateinit var vectorFeatures: VectorFeatures
@Inject lateinit var vectorLocale: VectorLocale
override var titleRes = R.string.settings_preferences override var titleRes = R.string.settings_preferences
override val preferenceXmlRes = R.xml.vector_settings_preferences override val preferenceXmlRes = R.xml.vector_settings_preferences
@ -198,7 +199,7 @@ class VectorSettingsPreferencesFragment :
private fun setUserInterfacePreferences() { private fun setUserInterfacePreferences() {
// Selected language // Selected language
selectedLanguagePreference.summary = VectorLocale.localeToLocalisedString(VectorLocale.applicationLocale) selectedLanguagePreference.summary = vectorLocale.localeToLocalisedString(vectorLocale.applicationLocale)
// Text size // Text size
textSizePreference.summary = getString(fontScalePreferences.getResolvedFontScaleValue().nameResId) textSizePreference.summary = getString(fontScalePreferences.getResolvedFontScaleValue().nameResId)

View File

@ -37,13 +37,15 @@ import javax.inject.Inject
class LocalePickerController @Inject constructor( class LocalePickerController @Inject constructor(
private val vectorPreferences: VectorPreferences, private val vectorPreferences: VectorPreferences,
private val stringProvider: StringProvider, private val stringProvider: StringProvider,
private val errorFormatter: ErrorFormatter private val errorFormatter: ErrorFormatter,
private val vectorLocale: VectorLocale,
) : TypedEpoxyController<LocalePickerViewState>() { ) : TypedEpoxyController<LocalePickerViewState>() {
var listener: Listener? = null var listener: Listener? = null
override fun buildModels(data: LocalePickerViewState?) { override fun buildModels(data: LocalePickerViewState?) {
val list = data?.locales ?: return val list = data?.locales ?: return
val currentLocale = data.currentLocale ?: return
val host = this val host = this
profileSectionItem { profileSectionItem {
@ -51,10 +53,10 @@ class LocalePickerController @Inject constructor(
title(host.stringProvider.getString(R.string.choose_locale_current_locale_title)) title(host.stringProvider.getString(R.string.choose_locale_current_locale_title))
} }
localeItem { localeItem {
id(data.currentLocale.toString()) id(currentLocale.toString())
title(VectorLocale.localeToLocalisedString(data.currentLocale).safeCapitalize(data.currentLocale)) title(host.vectorLocale.localeToLocalisedString(currentLocale).safeCapitalize(currentLocale))
if (host.vectorPreferences.developerMode()) { if (host.vectorPreferences.developerMode()) {
subtitle(VectorLocale.localeToLocalisedStringInfo(data.currentLocale)) subtitle(host.vectorLocale.localeToLocalisedStringInfo(currentLocale))
} }
clickListener { host.listener?.onUseCurrentClicked() } clickListener { host.listener?.onUseCurrentClicked() }
} }
@ -78,13 +80,13 @@ class LocalePickerController @Inject constructor(
} }
} else { } else {
list() list()
.filter { it.toString() != data.currentLocale.toString() } .filter { it.toString() != currentLocale.toString() }
.forEach { locale -> .forEach { locale ->
localeItem { localeItem {
id(locale.toString()) id(locale.toString())
title(VectorLocale.localeToLocalisedString(locale).safeCapitalize(locale)) title(host.vectorLocale.localeToLocalisedString(locale).safeCapitalize(locale))
if (host.vectorPreferences.developerMode()) { if (host.vectorPreferences.developerMode()) {
subtitle(VectorLocale.localeToLocalisedStringInfo(locale)) subtitle(host.vectorLocale.localeToLocalisedStringInfo(locale))
} }
clickListener { host.listener?.onLocaleClicked(locale) } clickListener { host.listener?.onLocaleClicked(locale) }
} }

View File

@ -30,7 +30,8 @@ import kotlinx.coroutines.launch
class LocalePickerViewModel @AssistedInject constructor( class LocalePickerViewModel @AssistedInject constructor(
@Assisted initialState: LocalePickerViewState, @Assisted initialState: LocalePickerViewState,
private val vectorConfiguration: VectorConfiguration private val vectorConfiguration: VectorConfiguration,
private val vectorLocale: VectorLocale,
) : VectorViewModel<LocalePickerViewState, LocalePickerAction, LocalePickerViewEvents>(initialState) { ) : VectorViewModel<LocalePickerViewState, LocalePickerAction, LocalePickerViewEvents>(initialState) {
@AssistedFactory @AssistedFactory
@ -39,8 +40,13 @@ class LocalePickerViewModel @AssistedInject constructor(
} }
init { init {
setState {
copy(
currentLocale = vectorLocale.applicationLocale
)
}
viewModelScope.launch { viewModelScope.launch {
val result = VectorLocale.getSupportedLocales() val result = vectorLocale.getSupportedLocales()
setState { setState {
copy( copy(
@ -59,7 +65,7 @@ class LocalePickerViewModel @AssistedInject constructor(
} }
private fun handleSelectLocale(action: LocalePickerAction.SelectLocale) { private fun handleSelectLocale(action: LocalePickerAction.SelectLocale) {
VectorLocale.saveApplicationLocale(action.locale) vectorLocale.saveApplicationLocale(action.locale)
vectorConfiguration.applyToApplicationContext() vectorConfiguration.applyToApplicationContext()
_viewEvents.post(LocalePickerViewEvents.RestartActivity) _viewEvents.post(LocalePickerViewEvents.RestartActivity)
} }

View File

@ -19,10 +19,9 @@ package im.vector.app.features.settings.locale
import com.airbnb.mvrx.Async import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.Uninitialized
import im.vector.app.features.settings.VectorLocale
import java.util.Locale import java.util.Locale
data class LocalePickerViewState( data class LocalePickerViewState(
val currentLocale: Locale = VectorLocale.applicationLocale, val currentLocale: Locale? = null,
val locales: Async<List<Locale>> = Uninitialized val locales: Async<List<Locale>> = Uninitialized
) : MavericksState ) : MavericksState