Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change app language flow to use Either type #3

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ package ch.protonmail.android.mailsettings.data.repository

import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
import arrow.core.Either
import arrow.core.raise.either
import ch.protonmail.android.mailcommon.domain.model.PreferencesError
import ch.protonmail.android.mailcommon.domain.repository.AppLocaleRepository
import ch.protonmail.android.mailsettings.domain.model.AppLanguage
import ch.protonmail.android.mailsettings.domain.repository.AppLanguageRepository
Expand All @@ -30,31 +33,43 @@ import javax.inject.Inject
class AppLanguageRepositoryImpl @Inject constructor(private val appLocaleRepository: AppLocaleRepository) :
AppLanguageRepository {

private val languagePreferenceFlow = MutableSharedFlow<AppLanguage?>(replay = 1)
private val languagePreferenceFlow = MutableSharedFlow<Either<PreferencesError, AppLanguage?>>(replay = 1)

override fun observe(): Flow<AppLanguage?> {
val savedAppLocales = AppCompatDelegate.getApplicationLocales()
val languageTag = savedAppLocales[0]?.toLanguageTag()
init {
val result = either<PreferencesError, AppLanguage?> {
val savedAppLocales = AppCompatDelegate.getApplicationLocales()
val languageTag = savedAppLocales[0]?.toLanguageTag()
val appLanguage = AppLanguage.fromTag(languageTag)
appLanguage
}.mapLeft { _ -> PreferencesError }

languagePreferenceFlow.tryEmit(AppLanguage.fromTag(languageTag))
languagePreferenceFlow.tryEmit(result)
}

override fun observe(): Flow<Either<PreferencesError, AppLanguage?>> {
return languagePreferenceFlow
}

override fun save(language: AppLanguage) {
val locales = LocaleListCompat.forLanguageTags(language.langTag)
AppCompatDelegate.setApplicationLocales(locales)
languagePreferenceFlow.tryEmit(language)
val result = either<PreferencesError, AppLanguage?> {
language
}.mapLeft { _ -> PreferencesError }

languagePreferenceFlow.tryEmit(result)
appLocaleRepository.refresh()
}

override fun clear() {
val emptyLocales = LocaleListCompat.getEmptyLocaleList()
AppCompatDelegate.setApplicationLocales(emptyLocales)
languagePreferenceFlow.tryEmit(null)

val result = either<PreferencesError, AppLanguage?> {
null
}.mapLeft { _ -> PreferencesError }

languagePreferenceFlow.tryEmit(result)
appLocaleRepository.refresh()
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ enum class AppLanguage(val langName: String, val langTag: String) {
UKRAINIAN("Українська", "uk");

companion object {
private val map = values().associateBy { it.langTag }
private val map = entries.associateBy { it.langTag }
fun fromTag(tag: String?): AppLanguage? = map[tag]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@

package ch.protonmail.android.mailsettings.domain.repository

import arrow.core.Either
import ch.protonmail.android.mailcommon.domain.model.PreferencesError
import ch.protonmail.android.mailsettings.domain.model.AppLanguage
import kotlinx.coroutines.flow.Flow

interface AppLanguageRepository {
fun observe(): Flow<AppLanguage?>
fun observe(): Flow<Either<PreferencesError, AppLanguage?>>
fun save(language: AppLanguage)
fun clear()
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@ class ObserveAppSettings @Inject constructor(
appLanguageRepository.observe(),
combinedContactsRepository.observe()
) { autoLockPref, alternativeRouting, customLanguage, combinedContacts ->
val hasAutoLock = autoLockPref.getOrElse { AutoLockPreference(isEnabled = false) }
val hasAutoLock = autoLockPref.getOrElse { AutoLockPreference(isEnabled = false) }.isEnabled
val hasCombinedContacts = (combinedContacts as Either.Right<CombinedContactsPreference>).value.isEnabled
val hasAlternativeRouting = (alternativeRouting as Either.Right<AlternativeRoutingPreference>).value.isEnabled
val customAppLanguage = customLanguage.getOrElse { null }?.langName

AppSettings(
hasAutoLock = hasAutoLock.isEnabled,
hasAutoLock = hasAutoLock,
hasAlternativeRouting = hasAlternativeRouting,
customAppLanguage = customLanguage?.langName,
customAppLanguage = customAppLanguage,
hasCombinedContacts = hasCombinedContacts
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ sealed class LanguageSettingsState {
val languages: List<LanguageUiModel>
) : LanguageSettingsState()

object Loading : LanguageSettingsState()
data object Loading : LanguageSettingsState()
}

data class LanguageUiModel(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package ch.protonmail.android.mailsettings.presentation.settings.language

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import arrow.core.Either
import ch.protonmail.android.mailsettings.domain.model.AppLanguage
import ch.protonmail.android.mailsettings.domain.repository.AppLanguageRepository
import ch.protonmail.android.mailsettings.presentation.settings.language.LanguageSettingsState.Loading
Expand All @@ -39,10 +40,19 @@ class LanguageSettingsViewModel @Inject constructor(

val state: Flow<LanguageSettingsState> = languageRepository
.observe()
.mapLatest { selectedLang ->
val languages = getAppLanguageUiModels(selectedLang).sortedBy { it.name }
val isSystemDefault = selectedLang == null
LanguageSettingsState.Data(isSystemDefault, languages)
.mapLatest { either ->
when (either) {
is Either.Right -> {
val selectedLang = either.value
val languages = getAppLanguageUiModels(selectedLang).sortedBy { it.name }
val isSystemDefault = selectedLang == null
LanguageSettingsState.Data(isSystemDefault, languages)
}
is Either.Left -> {
val defaultLanguages = getAppLanguageUiModels(null).sortedBy { it.name }
LanguageSettingsState.Data(isSystemDefault = true, languages = defaultLanguages)
}
}
}
.stateIn(
viewModelScope,
Expand All @@ -58,7 +68,7 @@ class LanguageSettingsViewModel @Inject constructor(
languageRepository.clear()
}

private fun getAppLanguageUiModels(selectedAppLanguage: AppLanguage?) = AppLanguage.values().map {
private fun getAppLanguageUiModels(selectedAppLanguage: AppLanguage?) = AppLanguage.entries.map {
LanguageUiModel(
language = it,
isSelected = it == selectedAppLanguage,
Expand Down