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 package ru.daemonlord.messenger.ui.chats
import android.content.Context
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow 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.model.AppThemeMode
import ru.daemonlord.messenger.domain.settings.repository.ThemeRepository import ru.daemonlord.messenger.domain.settings.repository.ThemeRepository
import ru.daemonlord.messenger.domain.search.repository.SearchRepository import ru.daemonlord.messenger.domain.search.repository.SearchRepository
import ru.daemonlord.messenger.R
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
@@ -42,6 +45,7 @@ class ChatListViewModel @Inject constructor(
private val chatSearchRepository: ChatSearchRepository, private val chatSearchRepository: ChatSearchRepository,
private val searchRepository: SearchRepository, private val searchRepository: SearchRepository,
private val themeRepository: ThemeRepository, private val themeRepository: ThemeRepository,
@ApplicationContext private val context: Context,
) : ViewModel() { ) : ViewModel() {
private val selectedTab = MutableStateFlow(ChatTab.ALL) private val selectedTab = MutableStateFlow(ChatTab.ALL)
@@ -232,7 +236,7 @@ class ChatListViewModel @Inject constructor(
handle = null, handle = null,
description = null, description = null,
memberIds = memberIds, memberIds = memberIds,
successMessage = "Group created.", successMessageResId = R.string.chat_list_info_group_created,
) )
} }
@@ -244,7 +248,7 @@ class ChatListViewModel @Inject constructor(
handle = handle, handle = handle,
description = description, description = description,
memberIds = emptyList(), memberIds = emptyList(),
successMessage = "Channel created.", successMessageResId = R.string.chat_list_info_channel_created,
) )
} }
@@ -254,7 +258,7 @@ class ChatListViewModel @Inject constructor(
is AppResult.Success -> { is AppResult.Success -> {
_uiState.update { _uiState.update {
it.copy( it.copy(
managementMessage = "Joined chat.", managementMessage = context.getString(R.string.chat_list_info_joined_chat),
pendingOpenChatId = result.data.id, pendingOpenChatId = result.data.id,
) )
} }
@@ -269,7 +273,7 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.leaveChat(chatId = chatId)) { when (val result = chatRepository.leaveChat(chatId = chatId)) {
is AppResult.Success -> { 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) refreshCurrentTab(forceRefresh = true)
} }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -281,7 +285,7 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.archiveChat(chatId = chatId)) { when (val result = chatRepository.archiveChat(chatId = chatId)) {
is AppResult.Success -> { is AppResult.Success -> {
_uiState.update { it.copy(managementMessage = "Чат архивирован.") } _uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_archived)) }
refreshCurrentTab(forceRefresh = true) refreshCurrentTab(forceRefresh = true)
} }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -293,7 +297,7 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.unarchiveChat(chatId = chatId)) { when (val result = chatRepository.unarchiveChat(chatId = chatId)) {
is AppResult.Success -> { is AppResult.Success -> {
_uiState.update { it.copy(managementMessage = "Чат возвращен из архива.") } _uiState.update { it.copy(managementMessage = context.getString(R.string.chat_list_info_unarchived)) }
refreshCurrentTab(forceRefresh = true) refreshCurrentTab(forceRefresh = true)
} }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -304,7 +308,7 @@ class ChatListViewModel @Inject constructor(
fun pinChat(chatId: Long) { fun pinChat(chatId: Long) {
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.pinChat(chatId = chatId)) { 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()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
} }
} }
@@ -313,7 +317,7 @@ class ChatListViewModel @Inject constructor(
fun unpinChat(chatId: Long) { fun unpinChat(chatId: Long) {
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.unpinChat(chatId = chatId)) { 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()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
} }
} }
@@ -322,7 +326,7 @@ class ChatListViewModel @Inject constructor(
fun clearChat(chatId: Long) { fun clearChat(chatId: Long) {
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.clearChat(chatId = chatId)) { 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()) } 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) { fun updateChatTitle(chatId: Long, title: String) {
val normalized = title.trim() val normalized = title.trim()
if (normalized.isBlank()) { 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 return
} }
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.updateChatTitle(chatId = chatId, title = normalized)) { 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()) } 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 normalizedTitle = title?.trim()?.ifBlank { null }
val normalizedDescription = description?.trim()?.ifBlank { null } val normalizedDescription = description?.trim()?.ifBlank { null }
if (normalizedTitle == null && normalizedDescription == 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 return
} }
viewModelScope.launch { viewModelScope.launch {
@@ -358,7 +362,7 @@ class ChatListViewModel @Inject constructor(
avatarUrl = null, 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()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
} }
} }
@@ -367,7 +371,7 @@ class ChatListViewModel @Inject constructor(
fun deleteChatForMe(chatId: Long) { fun deleteChatForMe(chatId: Long) {
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.removeChat(chatId = chatId, forAll = false)) { 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()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
} }
} }
@@ -376,7 +380,7 @@ class ChatListViewModel @Inject constructor(
fun deleteChatForAll(chatId: Long) { fun deleteChatForAll(chatId: Long) {
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.removeChat(chatId = chatId, forAll = true)) { 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()) } 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)) { when (val updated = chatRepository.updateChatNotifications(chatId = chatId, muted = !current.data.muted)) {
is AppResult.Success -> _uiState.update { is AppResult.Success -> _uiState.update {
it.copy( 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()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = updated.reason.toUiMessage()) }
@@ -404,7 +412,12 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.createInviteLink(chatId = chatId)) { when (val result = chatRepository.createInviteLink(chatId = chatId)) {
is AppResult.Success -> _uiState.update { 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()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
} }
@@ -415,7 +428,14 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.addMember(chatId = chatId, userId = userId)) { when (val result = chatRepository.addMember(chatId = chatId, userId = userId)) {
is AppResult.Success -> { 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) loadMembersAndBans(chatId)
} }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -427,7 +447,15 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.updateMemberRole(chatId = chatId, userId = userId, role = role)) { when (val result = chatRepository.updateMemberRole(chatId = chatId, userId = userId, role = role)) {
is AppResult.Success -> { 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) loadMembersAndBans(chatId)
} }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -439,7 +467,7 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.removeMember(chatId = chatId, userId = userId)) { when (val result = chatRepository.removeMember(chatId = chatId, userId = userId)) {
is AppResult.Success -> { 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) loadMembersAndBans(chatId)
} }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -451,7 +479,7 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.banMember(chatId = chatId, userId = userId)) { when (val result = chatRepository.banMember(chatId = chatId, userId = userId)) {
is AppResult.Success -> { 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) loadMembersAndBans(chatId)
} }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -463,7 +491,7 @@ class ChatListViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
when (val result = chatRepository.unbanMember(chatId = chatId, userId = userId)) { when (val result = chatRepository.unbanMember(chatId = chatId, userId = userId)) {
is AppResult.Success -> { 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) loadMembersAndBans(chatId)
} }
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) } is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -553,11 +581,11 @@ class ChatListViewModel @Inject constructor(
handle: String?, handle: String?,
description: String?, description: String?,
memberIds: List<Long>, memberIds: List<Long>,
successMessage: String, successMessageResId: Int,
) { ) {
val normalizedTitle = title.trim() val normalizedTitle = title.trim()
if (normalizedTitle.isBlank()) { 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 return
} }
viewModelScope.launch { viewModelScope.launch {
@@ -574,7 +602,7 @@ class ChatListViewModel @Inject constructor(
is AppResult.Success -> { is AppResult.Success -> {
_uiState.update { _uiState.update {
it.copy( it.copy(
managementMessage = successMessage, managementMessage = context.getString(successMessageResId),
pendingOpenChatId = result.data.id, pendingOpenChatId = result.data.id,
) )
} }
@@ -646,11 +674,11 @@ class ChatListViewModel @Inject constructor(
private fun AppError.toUiMessage(): String { private fun AppError.toUiMessage(): String {
return when (this) { return when (this) {
AppError.Network -> "Network error while syncing chats." AppError.Network -> context.getString(R.string.chat_list_error_network_sync)
AppError.Unauthorized -> "Session expired. Please log in again." AppError.Unauthorized -> context.getString(R.string.chat_list_error_session_expired)
AppError.InvalidCredentials -> "Authorization failed." AppError.InvalidCredentials -> context.getString(R.string.chat_list_error_authorization_failed)
is AppError.Server -> "Server error while loading chats." is AppError.Server -> context.getString(R.string.chat_list_error_server_loading)
is AppError.Unknown -> "Unknown error while loading chats." 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_night_mode">Ночной режим</string>
<string name="menu_create_group">Создать группу</string> <string name="menu_create_group">Создать группу</string>
<string name="menu_saved">Избранное</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_day_mode_enabled">Включен дневной режим.</string>
<string name="toast_night_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_night_mode">Night mode</string>
<string name="menu_create_group">Create group</string> <string name="menu_create_group">Create group</string>
<string name="menu_saved">Saved</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_day_mode_enabled">Day mode enabled.</string>
<string name="toast_night_mode_enabled">Night mode enabled.</string> <string name="toast_night_mode_enabled">Night mode enabled.</string>
<string name="chats_not_found">No chats found</string> <string name="chats_not_found">No chats found</string>