Files
forkmessager/client-mobile/chats/presentation/chat_list/ChatListViewModel.kt
2026-04-14 01:41:51 +03:00

93 lines
3.0 KiB
Kotlin

package chats.presentation.chat_list
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import chats.domain.model.Chat
import chats.domain.repository.ChatRepository
import chats.data.remote.signalr.ChatHubClient
import chats.data.remote.signalr.ChatEvent
import core.network.ServerConfig
import core.security.TokenManager
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import javax.inject.Inject
import chats.data.repository.toDomain
data class ChatListState(
val chats: List<Chat> = emptyList(),
val isLoading: Boolean = false,
val error: String? = null,
val isStoriesEnabled: Boolean = true
)
@HiltViewModel
class ChatListViewModel @Inject constructor(
private val repository: ChatRepository,
private val signalrClient: ChatHubClient,
private val serverConfig: ServerConfig,
private val tokenManager: TokenManager
) : ViewModel() {
private val _state = MutableStateFlow(ChatListState())
val state: StateFlow<ChatListState> = _state.asStateFlow()
init {
val isStoriesEnabled = try {
serverConfig.getServerConfig().features.stories
} catch (e: Exception) {
true
}
_state.update { it.copy(isStoriesEnabled = isStoriesEnabled) }
loadChats()
observeSignalREvents()
}
private fun getCurrentUserId(): String = tokenManager.getUserId() ?: ""
fun loadChats() {
viewModelScope.launch {
_state.update { it.copy(isLoading = true) }
try {
val chats = repository.getChats()
_state.update { it.copy(chats = chats, isLoading = false) }
} catch (e: Exception) {
_state.update { it.copy(isLoading = false, error = e.message) }
}
}
}
private fun observeSignalREvents() {
signalrClient.events
.onEach { event ->
when (event) {
is ChatEvent.NewMessage -> {
updateChatsWithNewMessage(event)
}
is ChatEvent.NewChat -> {
val currentUserId = getCurrentUserId()
_state.update { it.copy(chats = listOf(event.chat.toDomain(currentUserId)) + it.chats) }
}
else -> Unit
}
}
.launchIn(viewModelScope)
}
private fun updateChatsWithNewMessage(event: ChatEvent.NewMessage) {
_state.update { currentState ->
val updatedChats = currentState.chats.map { chat ->
if (chat.id == event.message.chatId) {
chat.copy(
lastMessage = event.message.toDomain(),
unreadCount = chat.unreadCount + 1
)
} else chat
}.sortedByDescending { it.lastMessage?.createdAt }
currentState.copy(chats = updatedChats)
}
}
}