update events logic
This commit is contained in:
+28
-22
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user