Localize chat list management messages
Some checks failed
Android CI / android (push) Failing after 6m28s
Android Release / release (push) Has started running
CI / test (push) Has been cancelled

This commit is contained in:
2026-03-11 20:52:27 +03:00
parent 27f2ad8001
commit f88d9a2a36
3 changed files with 114 additions and 30 deletions

View File

@@ -1,8 +1,10 @@
package ru.daemonlord.messenger.ui.chats
import android.content.Context
import androidx.appcompat.app.AppCompatDelegate
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
@@ -28,6 +30,7 @@ import ru.daemonlord.messenger.domain.realtime.usecase.HandleRealtimeEventsUseCa
import ru.daemonlord.messenger.domain.settings.model.AppThemeMode
import ru.daemonlord.messenger.domain.settings.repository.ThemeRepository
import ru.daemonlord.messenger.domain.search.repository.SearchRepository
import ru.daemonlord.messenger.R
import javax.inject.Inject
@HiltViewModel
@@ -42,6 +45,7 @@ class ChatListViewModel @Inject constructor(
private val chatSearchRepository: ChatSearchRepository,
private val searchRepository: SearchRepository,
private val themeRepository: ThemeRepository,
@ApplicationContext private val context: Context,
) : ViewModel() {
private val selectedTab = MutableStateFlow(ChatTab.ALL)
@@ -232,7 +236,7 @@ class ChatListViewModel @Inject constructor(
handle = null,
description = null,
memberIds = memberIds,
successMessage = "Group created.",
successMessageResId = R.string.chat_list_info_group_created,
)
}
@@ -244,7 +248,7 @@ class ChatListViewModel @Inject constructor(
handle = handle,
description = description,
memberIds = emptyList(),
successMessage = "Channel created.",
successMessageResId = R.string.chat_list_info_channel_created,
)
}
@@ -254,7 +258,7 @@ class ChatListViewModel @Inject constructor(
is AppResult.Success -> {
_uiState.update {
it.copy(
managementMessage = "Joined chat.",
managementMessage = context.getString(R.string.chat_list_info_joined_chat),
pendingOpenChatId = result.data.id,
)
}
@@ -269,7 +273,7 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch {
when (val result = chatRepository.leaveChat(chatId = chatId)) {
is AppResult.Success -> {
_uiState.update { it.copy(managementMessage = "Left chat.") }
_uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_left_chat)) }
refreshCurrentTab(forceRefresh = true)
}
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -281,7 +285,7 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch {
when (val result = chatRepository.archiveChat(chatId = chatId)) {
is AppResult.Success -> {
_uiState.update { it.copy(managementMessage = "Чат архивирован.") }
_uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_archived)) }
refreshCurrentTab(forceRefresh = true)
}
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -293,7 +297,7 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch {
when (val result = chatRepository.unarchiveChat(chatId = chatId)) {
is AppResult.Success -> {
_uiState.update { it.copy(managementMessage = "Чат возвращен из архива.") }
_uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_unarchived)) }
refreshCurrentTab(forceRefresh = true)
}
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -304,7 +308,7 @@ class ChatListViewModel @Inject constructor(
fun pinChat(chatId: Long) {
viewModelScope.launch {
when (val result = chatRepository.pinChat(chatId = chatId)) {
is AppResult.Success -> _uiState.update { it.copy(managementMessage = "Чат закреплен.") }
is AppResult.Success -> _uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_pinned)) }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
}
}
@@ -313,7 +317,7 @@ class ChatListViewModel @Inject constructor(
fun unpinChat(chatId: Long) {
viewModelScope.launch {
when (val result = chatRepository.unpinChat(chatId = chatId)) {
is AppResult.Success -> _uiState.update { it.copy(managementMessage = "Чат откреплен.") }
is AppResult.Success -> _uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_unpinned)) }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
}
}
@@ -322,7 +326,7 @@ class ChatListViewModel @Inject constructor(
fun clearChat(chatId: Long) {
viewModelScope.launch {
when (val result = chatRepository.clearChat(chatId = chatId)) {
is AppResult.Success -> _uiState.update { it.copy(managementMessage = "История чата очищена.") }
is AppResult.Success -> _uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_history_cleared)) }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
}
}
@@ -331,12 +335,12 @@ class ChatListViewModel @Inject constructor(
fun updateChatTitle(chatId: Long, title: String) {
val normalized = title.trim()
if (normalized.isBlank()) {
_uiState.update { it.copy(errorMessage = "Title is required.") }
_uiState.update { it.copy(errorMessage = context.getString(R.string.chat_list_error_title_required)) }
return
}
viewModelScope.launch {
when (val result = chatRepository.updateChatTitle(chatId = chatId, title = normalized)) {
is AppResult.Success -> _uiState.update { it.copy(managementMessage = "Title updated.") }
is AppResult.Success -> _uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_title_updated)) }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
}
}
@@ -346,7 +350,7 @@ class ChatListViewModel @Inject constructor(
val normalizedTitle = title?.trim()?.ifBlank { null }
val normalizedDescription = description?.trim()?.ifBlank { null }
if (normalizedTitle == null && normalizedDescription == null) {
_uiState.update { it.copy(errorMessage = "Provide title or description.") }
_uiState.update { it.copy(errorMessage = context.getString(R.string.chat_list_error_title_or_description_required)) }
return
}
viewModelScope.launch {
@@ -358,7 +362,7 @@ class ChatListViewModel @Inject constructor(
avatarUrl = null,
)
) {
is AppResult.Success -> _uiState.update { it.copy(managementMessage = "Profile updated.") }
is AppResult.Success -> _uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_profile_updated)) }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
}
}
@@ -367,7 +371,7 @@ class ChatListViewModel @Inject constructor(
fun deleteChatForMe(chatId: Long) {
viewModelScope.launch {
when (val result = chatRepository.removeChat(chatId = chatId, forAll = false)) {
is AppResult.Success -> _uiState.update { it.copy(managementMessage = "Чат удален.") }
is AppResult.Success -> _uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_deleted_for_me)) }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
}
}
@@ -376,7 +380,7 @@ class ChatListViewModel @Inject constructor(
fun deleteChatForAll(chatId: Long) {
viewModelScope.launch {
when (val result = chatRepository.removeChat(chatId = chatId, forAll = true)) {
is AppResult.Success -> _uiState.update { it.copy(managementMessage = "Чат удален для всех.") }
is AppResult.Success -> _uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_deleted_for_all)) }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
}
}
@@ -389,7 +393,11 @@ class ChatListViewModel @Inject constructor(
when (val updated = chatRepository.updateChatNotifications(chatId = chatId, muted = !current.data.muted)) {
is AppResult.Success -> _uiState.update {
it.copy(
managementMessage = if (updated.data.muted) "Уведомления выключены." else "Уведомления включены.",
managementMessage = if (updated.data.muted) {
context.getString(R.string.chat_list_info_notifications_disabled)
} else {
context.getString(R.string.chat_list_info_notifications_enabled)
},
)
}
is AppResult.Error -> _uiState.update { it.copy(errorMessage = updated.reason.toUiMessage()) }
@@ -404,7 +412,12 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch {
when (val result = chatRepository.createInviteLink(chatId = chatId)) {
is AppResult.Success -> _uiState.update {
it.copy(managementMessage = "Invite: ${result.data.inviteUrl}")
it.copy(
managementMessage = context.getString(
R.string.chat_list_info_invite_created,
result.data.inviteUrl,
),
)
}
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
}
@@ -415,7 +428,14 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch {
when (val result = chatRepository.addMember(chatId = chatId, userId = userId)) {
is AppResult.Success -> {
_uiState.update { it.copy(managementMessage = "Added ${result.data.name}") }
_uiState.update {
it.copy(
managementMessage = context.getString(
R.string.chat_list_info_member_added,
result.data.name,
),
)
}
loadMembersAndBans(chatId)
}
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -427,7 +447,15 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch {
when (val result = chatRepository.updateMemberRole(chatId = chatId, userId = userId, role = role)) {
is AppResult.Success -> {
_uiState.update { it.copy(managementMessage = "Role updated: ${result.data.name} -> ${result.data.role}") }
_uiState.update {
it.copy(
managementMessage = context.getString(
R.string.chat_list_info_member_role_updated,
result.data.name,
result.data.role,
),
)
}
loadMembersAndBans(chatId)
}
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -439,7 +467,7 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch {
when (val result = chatRepository.removeMember(chatId = chatId, userId = userId)) {
is AppResult.Success -> {
_uiState.update { it.copy(managementMessage = "Member removed.") }
_uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_member_removed)) }
loadMembersAndBans(chatId)
}
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -451,7 +479,7 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch {
when (val result = chatRepository.banMember(chatId = chatId, userId = userId)) {
is AppResult.Success -> {
_uiState.update { it.copy(managementMessage = "Member banned.") }
_uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_member_banned)) }
loadMembersAndBans(chatId)
}
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -463,7 +491,7 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch {
when (val result = chatRepository.unbanMember(chatId = chatId, userId = userId)) {
is AppResult.Success -> {
_uiState.update { it.copy(managementMessage = "Member unbanned.") }
_uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_member_unbanned)) }
loadMembersAndBans(chatId)
}
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -553,11 +581,11 @@ class ChatListViewModel @Inject constructor(
handle: String?,
description: String?,
memberIds: List<Long>,
successMessage: String,
successMessageResId: Int,
) {
val normalizedTitle = title.trim()
if (normalizedTitle.isBlank()) {
_uiState.update { it.copy(errorMessage = "Title is required.") }
_uiState.update { it.copy(errorMessage = context.getString(R.string.chat_list_error_title_required)) }
return
}
viewModelScope.launch {
@@ -574,7 +602,7 @@ class ChatListViewModel @Inject constructor(
is AppResult.Success -> {
_uiState.update {
it.copy(
managementMessage = successMessage,
managementMessage = context.getString(successMessageResId),
pendingOpenChatId = result.data.id,
)
}
@@ -646,11 +674,11 @@ class ChatListViewModel @Inject constructor(
private fun AppError.toUiMessage(): String {
return when (this) {
AppError.Network -> "Network error while syncing chats."
AppError.Unauthorized -> "Session expired. Please log in again."
AppError.InvalidCredentials -> "Authorization failed."
is AppError.Server -> "Server error while loading chats."
is AppError.Unknown -> "Unknown error while loading chats."
AppError.Network -> context.getString(R.string.chat_list_error_network_sync)
AppError.Unauthorized -> context.getString(R.string.chat_list_error_session_expired)
AppError.InvalidCredentials -> context.getString(R.string.chat_list_error_authorization_failed)
is AppError.Server -> context.getString(R.string.chat_list_error_server_loading)
is AppError.Unknown -> context.getString(R.string.chat_list_error_unknown_loading)
}
}

View File

@@ -38,6 +38,34 @@
<string name="menu_night_mode">Ночной режим</string>
<string name="menu_create_group">Создать группу</string>
<string name="menu_saved">Избранное</string>
<string name="chat_list_info_group_created">Группа создана.</string>
<string name="chat_list_info_channel_created">Канал создан.</string>
<string name="chat_list_info_joined_chat">Вы вступили в чат.</string>
<string name="chat_list_info_left_chat">Вы вышли из чата.</string>
<string name="chat_list_info_archived">Чат архивирован.</string>
<string name="chat_list_info_unarchived">Чат возвращен из архива.</string>
<string name="chat_list_info_pinned">Чат закреплен.</string>
<string name="chat_list_info_unpinned">Чат откреплен.</string>
<string name="chat_list_info_history_cleared">История чата очищена.</string>
<string name="chat_list_info_title_updated">Название обновлено.</string>
<string name="chat_list_info_profile_updated">Профиль обновлен.</string>
<string name="chat_list_info_deleted_for_me">Чат удален.</string>
<string name="chat_list_info_deleted_for_all">Чат удален для всех.</string>
<string name="chat_list_info_notifications_disabled">Уведомления выключены.</string>
<string name="chat_list_info_notifications_enabled">Уведомления включены.</string>
<string name="chat_list_info_invite_created">Приглашение: %1$s</string>
<string name="chat_list_info_member_added">Добавлен %1$s</string>
<string name="chat_list_info_member_role_updated">Роль обновлена: %1$s -&gt; %2$s</string>
<string name="chat_list_info_member_removed">Участник удален.</string>
<string name="chat_list_info_member_banned">Участник заблокирован.</string>
<string name="chat_list_info_member_unbanned">Участник разблокирован.</string>
<string name="chat_list_error_title_required">Требуется название.</string>
<string name="chat_list_error_title_or_description_required">Укажите название или описание.</string>
<string name="chat_list_error_network_sync">Ошибка сети при синхронизации чатов.</string>
<string name="chat_list_error_session_expired">Сессия истекла. Войдите снова.</string>
<string name="chat_list_error_authorization_failed">Ошибка авторизации.</string>
<string name="chat_list_error_server_loading">Ошибка сервера при загрузке чатов.</string>
<string name="chat_list_error_unknown_loading">Неизвестная ошибка при загрузке чатов.</string>
<string name="toast_day_mode_enabled">Включен дневной режим.</string>
<string name="toast_night_mode_enabled">Включен ночной режим.</string>

View File

@@ -19,6 +19,34 @@
<string name="menu_night_mode">Night mode</string>
<string name="menu_create_group">Create group</string>
<string name="menu_saved">Saved</string>
<string name="chat_list_info_group_created">Group created.</string>
<string name="chat_list_info_channel_created">Channel created.</string>
<string name="chat_list_info_joined_chat">Joined chat.</string>
<string name="chat_list_info_left_chat">Left chat.</string>
<string name="chat_list_info_archived">Chat archived.</string>
<string name="chat_list_info_unarchived">Chat restored from archive.</string>
<string name="chat_list_info_pinned">Chat pinned.</string>
<string name="chat_list_info_unpinned">Chat unpinned.</string>
<string name="chat_list_info_history_cleared">Chat history cleared.</string>
<string name="chat_list_info_title_updated">Title updated.</string>
<string name="chat_list_info_profile_updated">Profile updated.</string>
<string name="chat_list_info_deleted_for_me">Chat deleted.</string>
<string name="chat_list_info_deleted_for_all">Chat deleted for everyone.</string>
<string name="chat_list_info_notifications_disabled">Notifications disabled.</string>
<string name="chat_list_info_notifications_enabled">Notifications enabled.</string>
<string name="chat_list_info_invite_created">Invite: %1$s</string>
<string name="chat_list_info_member_added">Added %1$s</string>
<string name="chat_list_info_member_role_updated">Role updated: %1$s -&gt; %2$s</string>
<string name="chat_list_info_member_removed">Member removed.</string>
<string name="chat_list_info_member_banned">Member banned.</string>
<string name="chat_list_info_member_unbanned">Member unbanned.</string>
<string name="chat_list_error_title_required">Title is required.</string>
<string name="chat_list_error_title_or_description_required">Provide title or description.</string>
<string name="chat_list_error_network_sync">Network error while syncing chats.</string>
<string name="chat_list_error_session_expired">Session expired. Please log in again.</string>
<string name="chat_list_error_authorization_failed">Authorization failed.</string>
<string name="chat_list_error_server_loading">Server error while loading chats.</string>
<string name="chat_list_error_unknown_loading">Unknown error while loading chats.</string>
<string name="toast_day_mode_enabled">Day mode enabled.</string>
<string name="toast_night_mode_enabled">Night mode enabled.</string>
<string name="chats_not_found">No chats found</string>