123 lines
4.0 KiB
Kotlin
123 lines
4.0 KiB
Kotlin
package contacts.presentation
|
|
|
|
import androidx.lifecycle.ViewModel
|
|
import androidx.lifecycle.viewModelScope
|
|
import chats.domain.repository.ChatRepository
|
|
import contacts.domain.repository.ContactRepository
|
|
import core.utils.NavigationManager
|
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
import kotlinx.coroutines.flow.MutableStateFlow
|
|
import kotlinx.coroutines.flow.StateFlow
|
|
import kotlinx.coroutines.flow.asStateFlow
|
|
import kotlinx.coroutines.flow.update
|
|
import kotlinx.coroutines.launch
|
|
import javax.inject.Inject
|
|
|
|
data class ContactListState(
|
|
val contacts: List<contacts.data.remote.api.ContactDto> = emptyList(),
|
|
val requests: List<contacts.data.remote.api.FriendRequestDto> = emptyList(),
|
|
val isLoading: Boolean = false,
|
|
val error: String? = null
|
|
)
|
|
|
|
@HiltViewModel
|
|
class ContactListViewModel @Inject constructor(
|
|
private val contactRepository: ContactRepository,
|
|
private val chatRepository: ChatRepository,
|
|
private val navigationManager: NavigationManager
|
|
) : ViewModel() {
|
|
private val _state = MutableStateFlow(ContactListState())
|
|
val state: StateFlow<ContactListState> = _state.asStateFlow()
|
|
|
|
init {
|
|
loadData()
|
|
}
|
|
|
|
fun loadData() {
|
|
loadContacts()
|
|
loadRequests()
|
|
}
|
|
|
|
fun loadContacts() {
|
|
viewModelScope.launch {
|
|
_state.update { it.copy(isLoading = true, error = null) }
|
|
contactRepository.getContacts()
|
|
.onSuccess { contacts ->
|
|
_state.update { it.copy(contacts = contacts, isLoading = false) }
|
|
}
|
|
.onFailure { e ->
|
|
_state.update { it.copy(isLoading = false, error = e.message) }
|
|
}
|
|
}
|
|
}
|
|
|
|
fun loadRequests() {
|
|
viewModelScope.launch {
|
|
contactRepository.getFriendRequests()
|
|
.onSuccess { requests ->
|
|
_state.update { it.copy(requests = requests) }
|
|
}
|
|
}
|
|
}
|
|
|
|
fun onSearchChange(query: String) {
|
|
if (query.length < 3) {
|
|
if (query.isEmpty()) loadData()
|
|
return
|
|
}
|
|
|
|
viewModelScope.launch {
|
|
_state.update { it.copy(isLoading = true, error = null) }
|
|
contactRepository.searchUsers(query)
|
|
.onSuccess { users ->
|
|
_state.update { it.copy(contacts = users, isLoading = false) }
|
|
}
|
|
.onFailure { e ->
|
|
_state.update { it.copy(isLoading = false, error = e.message) }
|
|
}
|
|
}
|
|
}
|
|
|
|
fun addContact(userId: String) {
|
|
viewModelScope.launch {
|
|
contactRepository.addContact(userId)
|
|
.onSuccess {
|
|
loadData()
|
|
}
|
|
.onFailure { e ->
|
|
_state.update { it.copy(error = e.message) }
|
|
}
|
|
}
|
|
}
|
|
|
|
fun acceptRequest(requestId: String) {
|
|
viewModelScope.launch {
|
|
contactRepository.acceptRequest(requestId)
|
|
.onSuccess { loadData() }
|
|
.onFailure { e -> _state.update { it.copy(error = e.message) } }
|
|
}
|
|
}
|
|
|
|
fun declineRequest(requestId: String) {
|
|
viewModelScope.launch {
|
|
contactRepository.declineRequest(requestId)
|
|
.onSuccess { loadData() }
|
|
.onFailure { e -> _state.update { it.copy(error = e.message) } }
|
|
}
|
|
}
|
|
|
|
fun startChat(userId: String) {
|
|
viewModelScope.launch {
|
|
try {
|
|
// В вебе мы ищем существующий чат или создаем новый.
|
|
// В мобилке мы для начала можем просто вызвать createPersonalChat.
|
|
// Бэкенд обычно возвращает существующий чат, если он уже есть.
|
|
val chat = chatRepository.createPersonalChat(userId)
|
|
navigationManager.navigateToChat(chat.id)
|
|
} catch (e: Exception) {
|
|
_state.update { it.copy(error = e.message) }
|
|
}
|
|
}
|
|
}
|
|
}
|