This commit is contained in:
2026-09-14 19:28:39 +03:00
parent fce29831a2
commit 5ff633fc4d
3 changed files with 33 additions and 29 deletions
@@ -25,21 +25,22 @@ class AuthComponent(
private val authRepository: AuthRepository, private val authRepository: AuthRepository,
private val goToChat: () -> Unit private val goToChat: () -> Unit
) : ComponentContext by context { ) : ComponentContext by context {
private val scope = coroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
private val _state = MutableStateFlow(AuthState())
val state = _state.asStateFlow()
private val exceptionHandler = CoroutineExceptionHandler { _, throwable -> private val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
_state.value = AuthState(isLoading = false, error = throwable) _state.value = AuthState(isLoading = false, error = throwable)
} }
private val scope = coroutineScope(exceptionHandler + SupervisorJob() + Dispatchers.Main.immediate)
private val _state = MutableStateFlow(AuthState())
val state = _state.asStateFlow()
init { init {
scope.launch(exceptionHandler) { scope.launch {
if (tokenStorage.token.firstOrNull() != null) goToChat() if (tokenStorage.token.firstOrNull() != null) goToChat()
} }
} }
fun login(code: Int) { fun login(code: Int) {
scope.launch(exceptionHandler) { scope.launch {
_state.value = AuthState(isLoading = true, error = null) _state.value = AuthState(isLoading = true, error = null)
val token = authRepository.login(LoginRequest(code)) val token = authRepository.login(LoginRequest(code))
tokenStorage.updateToken(token) tokenStorage.updateToken(token)
@@ -89,11 +89,12 @@ private fun CodeStep(
} }
} }
val title = stringResource(R.string.auth_code_title)
val openCodeInput = { val openCodeInput = {
val intent = RemoteInputIntentHelper.createActionRemoteInputIntent() val intent = RemoteInputIntentHelper.createActionRemoteInputIntent()
val remoteInputs = listOf( val remoteInputs = listOf(
RemoteInput.Builder(CODE_INPUT_KEY) RemoteInput.Builder(CODE_INPUT_KEY)
.setLabel("Код") .setLabel(title)
.build() .build()
) )
RemoteInputIntentHelper.putRemoteInputsExtra(intent, remoteInputs) RemoteInputIntentHelper.putRemoteInputsExtra(intent, remoteInputs)
@@ -107,7 +108,7 @@ private fun CodeStep(
) { ) {
item { item {
WearText( WearText(
text = stringResource(R.string.auth_code_title), text = title,
style = MaterialTheme.typography.bodyMedium style = MaterialTheme.typography.bodyMedium
) )
} }
@@ -2,11 +2,14 @@ package ru.shadowsparky.gigawear.presentation.chat
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.childContext import com.arkivanov.decompose.childContext
import com.arkivanov.decompose.value.MutableValue
import com.arkivanov.decompose.value.Value
import com.arkivanov.decompose.value.update
import com.arkivanov.essenty.lifecycle.coroutines.coroutineScope import com.arkivanov.essenty.lifecycle.coroutines.coroutineScope
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.core.annotation.Factory import org.koin.core.annotation.Factory
@@ -25,11 +28,15 @@ class ChatComponent(
private val repository: ChatRepository, private val repository: ChatRepository,
private val updateComponentFactory: UpdateComponentFactory private val updateComponentFactory: UpdateComponentFactory
) : ComponentContext by context { ) : ComponentContext by context {
private val scope = coroutineScope() private val _state = MutableStateFlow(ChatUiState())
val state: StateFlow<ChatUiState> = _state.asStateFlow()
private val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
_state.value = ChatUiState(isLoading = false, error = throwable)
}
private val scope = coroutineScope(exceptionHandler + SupervisorJob() + Dispatchers.Main.immediate)
val updateComponent = updateComponentFactory.create(childContext("updater")) val updateComponent = updateComponentFactory.create(childContext("updater"))
private val _state = MutableValue(ChatUiState())
val state: Value<ChatUiState> = _state
private val _events = Channel<ComponentEvent>(Channel.BUFFERED) private val _events = Channel<ComponentEvent>(Channel.BUFFERED)
val events = _events.receiveAsFlow() val events = _events.receiveAsFlow()
@@ -46,21 +53,17 @@ class ChatComponent(
fun onSpeechRecognized(text: String) { fun onSpeechRecognized(text: String) {
_state.value = _state.value.copy(userText = text, isLoading = true, error = null) _state.value = _state.value.copy(userText = text, isLoading = true, error = null)
scope.launch { scope.launch {
try { val userMessage = Message(
val userMessage = Message( role = ChatRoles.USER,
role = ChatRoles.USER, content = text,
content = text, timestamp = System.currentTimeMillis()
timestamp = System.currentTimeMillis() )
) val responseMessage = repository.send(userMessage)
val responseMessage = repository.send(userMessage) _state.value = _state.value.copy(
_state.value = _state.value.copy( assistantText = responseMessage.content,
assistantText = responseMessage.content, isLoading = false
isLoading = false )
) _events.send(ComponentEvent.RequestSpeak(responseMessage.content))
_events.send(ComponentEvent.RequestSpeak(responseMessage.content))
} catch (e: Exception) {
_state.update { it.copy(error = e, isLoading = false) }
}
} }
} }
@@ -77,7 +80,6 @@ class ChatComponent(
) )
} }
@Factory @Factory
@Named(Route.CHAT) @Named(Route.CHAT)
class ChatComponentFactory( class ChatComponentFactory(