update events logic

This commit is contained in:
2026-08-03 21:42:50 +03:00
parent 986078a84c
commit 7fb482f46f
25 changed files with 208 additions and 303 deletions
@@ -3,11 +3,14 @@ package ru.shadowsparky.chat.presentation
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.value.MutableValue
import com.arkivanov.decompose.value.Value
import com.arkivanov.essenty.lifecycle.coroutines.repeatOnLifecycle
import com.arkivanov.essenty.lifecycle.doOnDestroy
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
import ru.shadowsparky.chat.domain.ChatRepository
import ru.shadowsparky.chat.domain.ChatRoles
@@ -31,10 +34,14 @@ class ChatComponent(
componentContext: ComponentContext,
private val repository: ChatRepository,
private val textParser: ChatTextParser?,
val onLinkClicked: (String) -> Unit
val onLinkClicked: (String) -> Unit,
val refreshFlow: Flow<Unit>
) : ComponentContext by componentContext {
private val errorHandler = CoroutineExceptionHandler { _, throwable ->
_state.value = ChatState.Error(throwable.message ?: throwable.toString())
}
private val scope = CoroutineScope(Dispatchers.Main.immediate + SupervisorJob()).also { ctx ->
private val scope = CoroutineScope(SupervisorJob() + errorHandler + Dispatchers.Main.immediate).also { ctx ->
lifecycle.doOnDestroy { ctx.cancel() }
}
@@ -43,6 +50,9 @@ class ChatComponent(
init {
loadInitialMessages()
scope.launch {
repeatOnLifecycle { refreshFlow.collect { refreshList() } }
}
}
fun parseMessage(content: String): List<TextToken> {
@@ -52,12 +62,8 @@ class ChatComponent(
fun loadInitialMessages() {
_state.value = ChatState.Loading
scope.launch {
try {
val dbList = repository.query(afterId = null)
_state.value = ChatState.Data(messages = dbList)
} catch (e: Exception) {
_state.value = ChatState.Error(e.message ?: e.toString())
}
val dbList = repository.query(afterId = null)
_state.value = ChatState.Data(messages = dbList)
}
}
@@ -66,20 +72,20 @@ class ChatComponent(
if (content.isBlank() || currentState.isSending) return
_state.value = currentState.copy(isSending = true, sendError = null)
scope.launch {
try {
repository.send(Message(role = ChatRoles.USER, content = content, timestamp = 0L))
val latestMessageId = currentState.messages.lastOrNull()?.id
val freshMessages = repository.query(afterId = latestMessageId)
_state.value = currentState.copy(
messages = currentState.messages + freshMessages,
isSending = false
)
} catch (e: Exception) {
_state.value = currentState.copy(
isSending = false,
sendError = e.message ?: e.toString()
)
}
repository.send(Message(role = ChatRoles.USER, content = content, timestamp = 0L))
}
}
private fun refreshList() {
val currentState = _state.value as? ChatState.Data ?: return
scope.launch {
_state.value = currentState.copy(isSending = true)
val latestMessageId = currentState.messages.lastOrNull()?.id
val freshMessages = repository.query(afterId = latestMessageId)
_state.value = currentState.copy(
messages = currentState.messages + freshMessages,
isSending = false
)
}
}