diff --git a/android/app/src/main/java/ru/daemonlord/messenger/ui/contacts/ContactsScreen.kt b/android/app/src/main/java/ru/daemonlord/messenger/ui/contacts/ContactsScreen.kt
index b121d29..375a9ed 100644
--- a/android/app/src/main/java/ru/daemonlord/messenger/ui/contacts/ContactsScreen.kt
+++ b/android/app/src/main/java/ru/daemonlord/messenger/ui/contacts/ContactsScreen.kt
@@ -30,12 +30,14 @@ import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.flow.collectLatest
+import ru.daemonlord.messenger.R
@Composable
fun ContactsRoute(
@@ -104,7 +106,7 @@ private fun ContactsScreen(
verticalArrangement = Arrangement.spacedBy(12.dp),
) {
TopAppBar(
- title = { Text("Contacts") },
+ title = { Text(stringResource(id = R.string.contacts_title)) },
)
PullToRefreshBox(
isRefreshing = state.isRefreshing,
@@ -122,7 +124,7 @@ private fun ContactsScreen(
onValueChange = onQueryChanged,
modifier = Modifier.fillMaxWidth(),
singleLine = true,
- label = { Text("Search contacts/users") },
+ label = { Text(stringResource(id = R.string.contacts_search_label)) },
)
Row(
modifier = Modifier.fillMaxWidth(),
@@ -134,10 +136,10 @@ private fun ContactsScreen(
onValueChange = onAddByEmailChanged,
modifier = Modifier.weight(1f),
singleLine = true,
- label = { Text("Add by email") },
+ label = { Text(stringResource(id = R.string.contacts_add_by_email_label)) },
)
Button(onClick = onAddContactByEmail) {
- Text("Add")
+ Text(stringResource(id = R.string.common_create))
}
}
@@ -172,7 +174,7 @@ private fun ContactsScreen(
if (state.isSearchingUsers || state.query.trim().length >= 2) {
item(key = "search_header") {
Text(
- text = "Search results",
+ text = stringResource(id = R.string.contacts_search_results),
style = MaterialTheme.typography.titleSmall,
fontWeight = FontWeight.SemiBold,
)
@@ -197,7 +199,7 @@ private fun ContactsScreen(
)
}
OutlinedButton(onClick = { onAddContact(user.id) }) {
- Text("Add")
+ Text(stringResource(id = R.string.common_create))
}
}
}
@@ -205,7 +207,7 @@ private fun ContactsScreen(
item(key = "contacts_header") {
Text(
- text = "My contacts",
+ text = stringResource(id = R.string.contacts_my_contacts),
style = MaterialTheme.typography.titleSmall,
fontWeight = FontWeight.SemiBold,
modifier = Modifier.padding(top = 4.dp),
@@ -226,13 +228,13 @@ private fun ContactsScreen(
overflow = TextOverflow.Ellipsis,
)
Text(
- text = contact.username?.let { "@$it" } ?: "last seen recently",
+ text = contact.username?.let { "@$it" } ?: stringResource(id = R.string.contacts_last_seen_recently),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
OutlinedButton(onClick = { onRemoveContact(contact.id) }) {
- Text("Remove")
+ Text(stringResource(id = R.string.contacts_remove))
}
}
}
@@ -240,7 +242,7 @@ private fun ContactsScreen(
if (state.contacts.isEmpty()) {
item(key = "empty_contacts") {
Text(
- text = "No contacts yet.",
+ text = stringResource(id = R.string.contacts_empty),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
diff --git a/android/app/src/main/java/ru/daemonlord/messenger/ui/contacts/ContactsViewModel.kt b/android/app/src/main/java/ru/daemonlord/messenger/ui/contacts/ContactsViewModel.kt
index 8d1d4fc..f590d51 100644
--- a/android/app/src/main/java/ru/daemonlord/messenger/ui/contacts/ContactsViewModel.kt
+++ b/android/app/src/main/java/ru/daemonlord/messenger/ui/contacts/ContactsViewModel.kt
@@ -2,7 +2,9 @@ package ru.daemonlord.messenger.ui.contacts
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.lifecycle.HiltViewModel
+import android.content.Context
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
@@ -10,6 +12,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
+import ru.daemonlord.messenger.R
import ru.daemonlord.messenger.domain.account.repository.AccountRepository
import ru.daemonlord.messenger.domain.common.AppError
import ru.daemonlord.messenger.domain.common.AppResult
@@ -18,6 +21,7 @@ import javax.inject.Inject
@HiltViewModel
class ContactsViewModel @Inject constructor(
private val accountRepository: AccountRepository,
+ @ApplicationContext private val context: Context,
) : ViewModel() {
private val _uiState = MutableStateFlow(ContactsUiState())
@@ -76,7 +80,7 @@ class ContactsViewModel @Inject constructor(
viewModelScope.launch {
when (val result = accountRepository.addContact(userId = userId)) {
is AppResult.Success -> {
- _uiState.update { it.copy(infoMessage = "Contact added.") }
+ _uiState.update { it.copy(infoMessage = context.getString(R.string.contacts_info_added)) }
loadContacts(forceRefresh = true)
}
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -87,7 +91,7 @@ class ContactsViewModel @Inject constructor(
fun addContactByEmail() {
val email = uiState.value.addByEmail.trim()
if (email.isBlank()) {
- _uiState.update { it.copy(errorMessage = "Email is required.") }
+ _uiState.update { it.copy(errorMessage = context.getString(R.string.contacts_error_email_required)) }
return
}
viewModelScope.launch {
@@ -96,7 +100,7 @@ class ContactsViewModel @Inject constructor(
_uiState.update {
it.copy(
addByEmail = "",
- infoMessage = "Contact added by email.",
+ infoMessage = context.getString(R.string.contacts_info_added_by_email),
)
}
loadContacts(forceRefresh = true)
@@ -110,7 +114,7 @@ class ContactsViewModel @Inject constructor(
viewModelScope.launch {
when (val result = accountRepository.removeContact(userId = userId)) {
is AppResult.Success -> {
- _uiState.update { it.copy(infoMessage = "Contact removed.") }
+ _uiState.update { it.copy(infoMessage = context.getString(R.string.contacts_info_removed)) }
loadContacts(forceRefresh = true)
}
is AppResult.Error -> _uiState.update { it.copy(errorMessage = result.reason.toUiMessage()) }
@@ -148,11 +152,11 @@ class ContactsViewModel @Inject constructor(
private fun AppError.toUiMessage(): String {
return when (this) {
- AppError.Network -> "Network error."
- AppError.Unauthorized -> "Session expired."
- AppError.InvalidCredentials -> "Authorization error."
- is AppError.Server -> this.message ?: "Server error."
- is AppError.Unknown -> this.cause?.message ?: "Unknown error."
+ AppError.Network -> context.getString(R.string.error_network)
+ AppError.Unauthorized -> context.getString(R.string.error_session_expired)
+ AppError.InvalidCredentials -> context.getString(R.string.error_authorization)
+ is AppError.Server -> this.message ?: context.getString(R.string.error_server)
+ is AppError.Unknown -> this.cause?.message ?: context.getString(R.string.error_unknown)
}
}
}
diff --git a/android/app/src/main/res/values-ru/strings.xml b/android/app/src/main/res/values-ru/strings.xml
index 883b8ed..40f0037 100644
--- a/android/app/src/main/res/values-ru/strings.xml
+++ b/android/app/src/main/res/values-ru/strings.xml
@@ -208,4 +208,22 @@
Отправить ссылку сброса
Новый пароль
Сбросить по токену
+
+ Контакты
+ Поиск контактов/пользователей
+ Добавить по email
+ Результаты поиска
+ Мои контакты
+ был(а) недавно
+ Удалить
+ Контактов пока нет.
+ Контакт добавлен.
+ Контакт добавлен по email.
+ Контакт удален.
+ Требуется email.
+ Ошибка сети.
+ Сессия истекла.
+ Ошибка авторизации.
+ Ошибка сервера.
+ Неизвестная ошибка.
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
index 67224a5..f1ee1d0 100644
--- a/android/app/src/main/res/values/strings.xml
+++ b/android/app/src/main/res/values/strings.xml
@@ -208,4 +208,22 @@
Send reset link
New password
Reset with token
+
+ Contacts
+ Search contacts/users
+ Add by email
+ Search results
+ My contacts
+ last seen recently
+ Remove
+ No contacts yet.
+ Contact added.
+ Contact added by email.
+ Contact removed.
+ Email is required.
+ Network error.
+ Session expired.
+ Authorization error.
+ Server error.
+ Unknown error.