diff --git a/apps/giga-wear/client/build.gradle.kts b/apps/giga-wear/client/build.gradle.kts index 0e8fc35..52e4cfd 100644 --- a/apps/giga-wear/client/build.gradle.kts +++ b/apps/giga-wear/client/build.gradle.kts @@ -8,7 +8,7 @@ plugins { alias(libs.plugins.convention.serialization) } -val appVersion = "1.0.3" +val appVersion = "1.0.4" android { buildFeatures { buildConfig = true } diff --git a/apps/giga-wear/client/src/main/kotlin/ru/shadowsparky/gigawear/presentation/MainActivity.kt b/apps/giga-wear/client/src/main/kotlin/ru/shadowsparky/gigawear/presentation/MainActivity.kt index d3b578f..dd33b56 100644 --- a/apps/giga-wear/client/src/main/kotlin/ru/shadowsparky/gigawear/presentation/MainActivity.kt +++ b/apps/giga-wear/client/src/main/kotlin/ru/shadowsparky/gigawear/presentation/MainActivity.kt @@ -3,7 +3,9 @@ package ru.shadowsparky.gigawear.presentation import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.lifecycle.lifecycleScope import com.arkivanov.decompose.retainedComponent +import kotlinx.coroutines.launch import org.koin.android.ext.android.inject import ru.shadowsparky.gigawear.presentation.auth.AuthScreen import ru.shadowsparky.gigawear.presentation.chat.ChatScreen @@ -17,6 +19,9 @@ class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val root = retainedComponent { rootFactory.create(it) } + lifecycleScope.launch { + root.onFinish.collect { finishAffinity() } + } setContent { Nav(root) { child, _ -> when (child) { diff --git a/apps/giga-wear/client/src/main/kotlin/ru/shadowsparky/gigawear/presentation/chat/ChatComponent.kt b/apps/giga-wear/client/src/main/kotlin/ru/shadowsparky/gigawear/presentation/chat/ChatComponent.kt index 019ad1a..29e1233 100644 --- a/apps/giga-wear/client/src/main/kotlin/ru/shadowsparky/gigawear/presentation/chat/ChatComponent.kt +++ b/apps/giga-wear/client/src/main/kotlin/ru/shadowsparky/gigawear/presentation/chat/ChatComponent.kt @@ -2,12 +2,13 @@ package ru.shadowsparky.gigawear.presentation.chat import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.childContext +import com.arkivanov.essenty.backhandler.BackCallback import com.arkivanov.essenty.lifecycle.coroutines.coroutineScope import com.arkivanov.essenty.lifecycle.doOnStart -import com.arkivanov.essenty.lifecycle.doOnStop import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -32,6 +33,7 @@ class ChatComponent( private val repository: ChatRepository, updateComponentFactory: UpdateComponentFactory, private val tokenStorage: TokenStorage, + private val onBack: () -> Unit, private val navigateToRouting: () -> Unit ) : ComponentContext by context { private val _state = MutableStateFlow(ChatUiState()) @@ -55,8 +57,23 @@ class ChatComponent( if (it == null) navigateToRouting() } } - lifecycle.doOnStop { - _state.update { it.copy(stopRequested = true) } + registerBackCallback() + } + + private fun registerBackCallback() { + scope.launch { + val backCallback = object : BackCallback() { + override fun onBack() { + _state.update { it.copy(stopRequested = true) } + onBack.invoke() + } + } + try { + backHandler.register(backCallback) + awaitCancellation() + } finally { + backHandler.unregister(backCallback) + } } } @@ -118,7 +135,8 @@ class ChatComponentFactory( child, chatRepository, updateComponentFactory, - tokenStorage + tokenStorage, + onBack = { root.onBack() } ) { root.navReplace(Route.RoutingScreen()) } return Child.MainChild(component) } diff --git a/apps/giga-wear/client/src/main/kotlin/ru/shadowsparky/gigawear/presentation/chat/SpeechManager.kt b/apps/giga-wear/client/src/main/kotlin/ru/shadowsparky/gigawear/presentation/chat/SpeechManager.kt index 1f40157..31f43b6 100644 --- a/apps/giga-wear/client/src/main/kotlin/ru/shadowsparky/gigawear/presentation/chat/SpeechManager.kt +++ b/apps/giga-wear/client/src/main/kotlin/ru/shadowsparky/gigawear/presentation/chat/SpeechManager.kt @@ -44,13 +44,18 @@ class SpeechManager(context: Context) { fun speak(text: String) { tts?.speak( - text, + filterText(text), TextToSpeech.QUEUE_FLUSH, null, UTTERANCE_ID ) } + private fun filterText(text: String): String = + text.replace(Regex("[^A-Za-zА-Яа-яЁё0-9\\s.,!?]"), "") + .replace(Regex("\\s+"), " ") + .trim() + fun stop() { tts?.stop() resetSpeaking()