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) }
|
||
}
|
||
}
|
||
}
|
||
}
|