Localize AccountViewModel status and error messages
This commit is contained in:
@@ -1,9 +1,11 @@
|
|||||||
package ru.daemonlord.messenger.ui.account
|
package ru.daemonlord.messenger.ui.account
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.core.os.LocaleListCompat
|
import androidx.core.os.LocaleListCompat
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
@@ -23,6 +25,7 @@ import ru.daemonlord.messenger.domain.settings.model.AppLanguage
|
|||||||
import ru.daemonlord.messenger.domain.settings.model.AppThemeMode
|
import ru.daemonlord.messenger.domain.settings.model.AppThemeMode
|
||||||
import ru.daemonlord.messenger.domain.settings.repository.LanguageRepository
|
import ru.daemonlord.messenger.domain.settings.repository.LanguageRepository
|
||||||
import ru.daemonlord.messenger.domain.settings.repository.ThemeRepository
|
import ru.daemonlord.messenger.domain.settings.repository.ThemeRepository
|
||||||
|
import ru.daemonlord.messenger.R
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@@ -36,6 +39,7 @@ class AccountViewModel @Inject constructor(
|
|||||||
private val languageRepository: LanguageRepository,
|
private val languageRepository: LanguageRepository,
|
||||||
private val themeRepository: ThemeRepository,
|
private val themeRepository: ThemeRepository,
|
||||||
private val pushTokenSyncManager: PushTokenSyncManager,
|
private val pushTokenSyncManager: PushTokenSyncManager,
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
private val _uiState = MutableStateFlow(AccountUiState())
|
private val _uiState = MutableStateFlow(AccountUiState())
|
||||||
val uiState: StateFlow<AccountUiState> = _uiState.asStateFlow()
|
val uiState: StateFlow<AccountUiState> = _uiState.asStateFlow()
|
||||||
@@ -65,13 +69,14 @@ class AccountViewModel @Inject constructor(
|
|||||||
notificationsHistory = (notifications as? AppResult.Success)?.data ?: state.notificationsHistory,
|
notificationsHistory = (notifications as? AppResult.Success)?.data ?: state.notificationsHistory,
|
||||||
activeUserId = activeUserId,
|
activeUserId = activeUserId,
|
||||||
storedAccounts = storedAccounts.map { account ->
|
storedAccounts = storedAccounts.map { account ->
|
||||||
|
val fallbackUser = context.getString(R.string.account_user_fallback, account.userId)
|
||||||
StoredAccountUi(
|
StoredAccountUi(
|
||||||
userId = account.userId,
|
userId = account.userId,
|
||||||
title = account.name.ifBlank { "User #${account.userId}" },
|
title = account.name.ifBlank { fallbackUser },
|
||||||
subtitle = listOfNotNull(
|
subtitle = listOfNotNull(
|
||||||
account.username?.takeIf { it.isNotBlank() }?.let { "@$it" },
|
account.username?.takeIf { it.isNotBlank() }?.let { "@$it" },
|
||||||
account.email?.takeIf { it.isNotBlank() },
|
account.email?.takeIf { it.isNotBlank() },
|
||||||
).joinToString(" • ").ifBlank { "User #${account.userId}" },
|
).joinToString(" • ").ifBlank { fallbackUser },
|
||||||
avatarUrl = account.avatarUrl,
|
avatarUrl = account.avatarUrl,
|
||||||
isActive = activeUserId == account.userId,
|
isActive = activeUserId == account.userId,
|
||||||
)
|
)
|
||||||
@@ -131,7 +136,7 @@ class AccountViewModel @Inject constructor(
|
|||||||
fun addAccount(email: String, password: String, onDone: (Boolean) -> Unit = {}) {
|
fun addAccount(email: String, password: String, onDone: (Boolean) -> Unit = {}) {
|
||||||
val normalizedEmail = email.trim()
|
val normalizedEmail = email.trim()
|
||||||
if (normalizedEmail.isBlank() || password.isBlank()) {
|
if (normalizedEmail.isBlank() || password.isBlank()) {
|
||||||
_uiState.update { it.copy(errorMessage = "Email and password are required.") }
|
_uiState.update { it.copy(errorMessage = context.getString(R.string.account_error_email_password_required)) }
|
||||||
onDone(false)
|
onDone(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -142,7 +147,7 @@ class AccountViewModel @Inject constructor(
|
|||||||
_uiState.update {
|
_uiState.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
isAddingAccount = false,
|
isAddingAccount = false,
|
||||||
message = "Account added.",
|
message = context.getString(R.string.account_info_added),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
refresh()
|
refresh()
|
||||||
@@ -165,7 +170,7 @@ class AccountViewModel @Inject constructor(
|
|||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val switched = tokenRepository.switchAccount(userId)
|
val switched = tokenRepository.switchAccount(userId)
|
||||||
if (!switched) {
|
if (!switched) {
|
||||||
_uiState.update { it.copy(errorMessage = "No saved session for this account.") }
|
_uiState.update { it.copy(errorMessage = context.getString(R.string.account_error_no_saved_session)) }
|
||||||
onSwitched(false)
|
onSwitched(false)
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
@@ -180,7 +185,7 @@ class AccountViewModel @Inject constructor(
|
|||||||
if (syncFailed) {
|
if (syncFailed) {
|
||||||
_uiState.update {
|
_uiState.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
errorMessage = "Account switched, but chats sync failed. Pull to refresh.",
|
errorMessage = context.getString(R.string.account_error_switch_sync_failed),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,7 +213,7 @@ class AccountViewModel @Inject constructor(
|
|||||||
it.copy(
|
it.copy(
|
||||||
isSaving = false,
|
isSaving = false,
|
||||||
profile = result.data,
|
profile = result.data,
|
||||||
message = "Profile updated.",
|
message = context.getString(R.string.account_info_profile_updated),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is AppResult.Error -> _uiState.update {
|
is AppResult.Error -> _uiState.update {
|
||||||
@@ -231,7 +236,7 @@ class AccountViewModel @Inject constructor(
|
|||||||
_uiState.update { it.copy(isSaving = true, errorMessage = null, message = null) }
|
_uiState.update { it.copy(isSaving = true, errorMessage = null, message = null) }
|
||||||
when (val result = accountRepository.uploadAvatar(fileName, mimeType, bytes)) {
|
when (val result = accountRepository.uploadAvatar(fileName, mimeType, bytes)) {
|
||||||
is AppResult.Success -> {
|
is AppResult.Success -> {
|
||||||
_uiState.update { it.copy(isSaving = false, message = "Avatar uploaded.") }
|
_uiState.update { it.copy(isSaving = false, message = context.getString(R.string.account_info_avatar_uploaded)) }
|
||||||
onUploaded(result.data)
|
onUploaded(result.data)
|
||||||
}
|
}
|
||||||
is AppResult.Error -> _uiState.update {
|
is AppResult.Error -> _uiState.update {
|
||||||
@@ -264,7 +269,7 @@ class AccountViewModel @Inject constructor(
|
|||||||
it.copy(
|
it.copy(
|
||||||
isSaving = false,
|
isSaving = false,
|
||||||
profile = result.data,
|
profile = result.data,
|
||||||
message = "Privacy settings updated.",
|
message = context.getString(R.string.account_info_privacy_updated),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is AppResult.Error -> _uiState.update {
|
is AppResult.Error -> _uiState.update {
|
||||||
@@ -317,7 +322,7 @@ class AccountViewModel @Inject constructor(
|
|||||||
it.copy(
|
it.copy(
|
||||||
twoFactorSecret = result.data.first,
|
twoFactorSecret = result.data.first,
|
||||||
twoFactorOtpAuthUrl = result.data.second,
|
twoFactorOtpAuthUrl = result.data.second,
|
||||||
message = "2FA secret generated. Enter code to enable.",
|
message = context.getString(R.string.account_info_2fa_secret_generated),
|
||||||
errorMessage = null,
|
errorMessage = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -366,7 +371,7 @@ class AccountViewModel @Inject constructor(
|
|||||||
is AppResult.Success -> _uiState.update {
|
is AppResult.Success -> _uiState.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
recoveryCodes = result.data,
|
recoveryCodes = result.data,
|
||||||
message = "Recovery codes regenerated.",
|
message = context.getString(R.string.account_info_recovery_codes_regenerated),
|
||||||
errorMessage = null,
|
errorMessage = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -461,11 +466,11 @@ class AccountViewModel @Inject constructor(
|
|||||||
|
|
||||||
private fun AppError.toUiMessage(): String {
|
private fun AppError.toUiMessage(): String {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
AppError.InvalidCredentials -> "Invalid credentials."
|
AppError.InvalidCredentials -> context.getString(R.string.account_error_invalid_credentials)
|
||||||
AppError.Unauthorized -> "Unauthorized."
|
AppError.Unauthorized -> context.getString(R.string.account_error_unauthorized)
|
||||||
AppError.Network -> "Network error."
|
AppError.Network -> context.getString(R.string.error_network)
|
||||||
is AppError.Server -> message ?: "Server error."
|
is AppError.Server -> message ?: context.getString(R.string.error_server)
|
||||||
is AppError.Unknown -> cause?.message ?: "Unknown error."
|
is AppError.Unknown -> cause?.message ?: context.getString(R.string.error_unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -263,4 +263,16 @@
|
|||||||
<string name="error_authorization">Ошибка авторизации.</string>
|
<string name="error_authorization">Ошибка авторизации.</string>
|
||||||
<string name="error_server">Ошибка сервера.</string>
|
<string name="error_server">Ошибка сервера.</string>
|
||||||
<string name="error_unknown">Неизвестная ошибка.</string>
|
<string name="error_unknown">Неизвестная ошибка.</string>
|
||||||
|
<string name="account_user_fallback">Пользователь #%1$d</string>
|
||||||
|
<string name="account_error_email_password_required">Нужны email и пароль.</string>
|
||||||
|
<string name="account_info_added">Аккаунт добавлен.</string>
|
||||||
|
<string name="account_error_no_saved_session">Для этого аккаунта нет сохраненной сессии.</string>
|
||||||
|
<string name="account_error_switch_sync_failed">Аккаунт переключен, но синхронизация чатов не удалась. Потяните вниз для обновления.</string>
|
||||||
|
<string name="account_info_profile_updated">Профиль обновлен.</string>
|
||||||
|
<string name="account_info_avatar_uploaded">Аватар загружен.</string>
|
||||||
|
<string name="account_info_privacy_updated">Настройки приватности обновлены.</string>
|
||||||
|
<string name="account_info_2fa_secret_generated">Секрет 2FA сгенерирован. Введите код для включения.</string>
|
||||||
|
<string name="account_info_recovery_codes_regenerated">Коды восстановления перегенерированы.</string>
|
||||||
|
<string name="account_error_invalid_credentials">Неверные учетные данные.</string>
|
||||||
|
<string name="account_error_unauthorized">Не авторизовано.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -263,4 +263,16 @@
|
|||||||
<string name="error_authorization">Authorization error.</string>
|
<string name="error_authorization">Authorization error.</string>
|
||||||
<string name="error_server">Server error.</string>
|
<string name="error_server">Server error.</string>
|
||||||
<string name="error_unknown">Unknown error.</string>
|
<string name="error_unknown">Unknown error.</string>
|
||||||
|
<string name="account_user_fallback">User #%1$d</string>
|
||||||
|
<string name="account_error_email_password_required">Email and password are required.</string>
|
||||||
|
<string name="account_info_added">Account added.</string>
|
||||||
|
<string name="account_error_no_saved_session">No saved session for this account.</string>
|
||||||
|
<string name="account_error_switch_sync_failed">Account switched, but chats sync failed. Pull to refresh.</string>
|
||||||
|
<string name="account_info_profile_updated">Profile updated.</string>
|
||||||
|
<string name="account_info_avatar_uploaded">Avatar uploaded.</string>
|
||||||
|
<string name="account_info_privacy_updated">Privacy settings updated.</string>
|
||||||
|
<string name="account_info_2fa_secret_generated">2FA secret generated. Enter code to enable.</string>
|
||||||
|
<string name="account_info_recovery_codes_regenerated">Recovery codes regenerated.</string>
|
||||||
|
<string name="account_error_invalid_credentials">Invalid credentials.</string>
|
||||||
|
<string name="account_error_unauthorized">Unauthorized.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user