From d87556ac35418fce6bb6184af60a0087e1133cf7 Mon Sep 17 00:00:00 2001 From: kaleidot725 Date: Wed, 29 May 2024 22:39:27 +0900 Subject: [PATCH] feat: add tab key --- .../kotlin/jp/kaleidot725/adbpad/Main.kt | 7 +++- .../adbpad/domain/di/DomainModule.kt | 4 +++ .../adbpad/domain/model/command/KeyCommand.kt | 10 ++++++ .../adbpad/domain/model/language/Language.kt | 10 ++++++ .../language/resources/EnglishResources.kt | 5 +++ .../language/resources/JapaneseResources.kt | 5 +++ .../language/resources/StringResources.kt | 5 +++ .../adbpad/domain/model/log/Event.kt | 24 +++++++++++++ .../domain/repository/KeyCommandRepository.kt | 13 +++++++ .../usecase/text/SendTabCommandUseCase.kt | 36 +++++++++++++++++++ .../adbpad/repository/di/RepositoryModule.kt | 5 +++ .../impl/KeyCommandRepositoryImpl.kt | 33 +++++++++++++++++ .../component/language/LanguageDropButton.kt | 2 -- .../component/text/InputTextActionMenu.kt | 22 ++++++++++++ .../adbpad/view/di/StateHolderModule.kt | 1 + .../view/screen/text/TextCommandScreen.kt | 9 +++++ .../view/screen/text/TextCommandState.kt | 2 ++ .../screen/text/TextCommandStateHolder.kt | 32 ++++++++++++----- 18 files changed, 214 insertions(+), 11 deletions(-) create mode 100644 src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/command/KeyCommand.kt create mode 100644 src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/repository/KeyCommandRepository.kt create mode 100644 src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/SendTabCommandUseCase.kt create mode 100644 src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/impl/KeyCommandRepositoryImpl.kt diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/Main.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/Main.kt index e296817f..a6a6806e 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/Main.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/Main.kt @@ -306,6 +306,10 @@ private fun DeviceContent( inputTextStateHolder.sendInputText() }, canSendInputText = inputTextState.canSendInputText, + canSendTabKey = inputTextState.canSendTabKey, + onSendTabKey = { + inputTextStateHolder.sendTabCommand() + }, onSaveInputText = { inputTextStateHolder.saveInputText() }, @@ -313,9 +317,10 @@ private fun DeviceContent( // Commands commands = inputTextState.commands, onSendCommand = { text -> - inputTextStateHolder.sendCommand(text) + inputTextStateHolder.sendTextCommand(text) }, canSendCommand = inputTextState.canSendCommand, + isSendingTab = inputTextState.isSendingTab, onDeleteCommand = { text -> inputTextStateHolder.deleteInputText(text) }, diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/di/DomainModule.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/di/DomainModule.kt index 400341a7..6177e498 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/di/DomainModule.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/di/DomainModule.kt @@ -23,6 +23,7 @@ import jp.kaleidot725.adbpad.domain.usecase.text.AddTextCommandUseCase import jp.kaleidot725.adbpad.domain.usecase.text.DeleteTextCommandUseCase import jp.kaleidot725.adbpad.domain.usecase.text.ExecuteTextCommandUseCase import jp.kaleidot725.adbpad.domain.usecase.text.GetTextCommandUseCase +import jp.kaleidot725.adbpad.domain.usecase.text.SendTabCommandUseCase import jp.kaleidot725.adbpad.domain.usecase.text.SendUserInputTextCommandUseCase import jp.kaleidot725.adbpad.domain.usecase.theme.GetDarkModeFlowUseCase import jp.kaleidot725.adbpad.domain.usecase.window.GetWindowSizeUseCase @@ -112,4 +113,7 @@ val domainModule = factory { CopyScreenshotToClipboardUseCase(get(), get()) } + factory { + SendTabCommandUseCase(get(), get()) + } } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/command/KeyCommand.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/command/KeyCommand.kt new file mode 100644 index 00000000..c1bb789b --- /dev/null +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/command/KeyCommand.kt @@ -0,0 +1,10 @@ +package jp.kaleidot725.adbpad.domain.model.command + +import com.malinskiy.adam.request.shell.v1.ShellCommandRequest + +data class KeyCommand( + val keycode: Int, + val isRunning: Boolean = false, +) { + val requests: List = listOf(ShellCommandRequest("input keyevent $keycode")) +} diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/Language.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/Language.kt index 3ce9953f..ad88c872 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/Language.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/Language.kt @@ -19,6 +19,8 @@ object Language : StringResources { get() = getCurrentResources().notFoundScreenshot override val execute: String get() = getCurrentResources().execute + override val tab: String + get() = getCurrentResources().tab override val save: String get() = getCurrentResources().save override val delete: String @@ -120,6 +122,14 @@ object Language : StringResources { get() = getCurrentResources().textCommandEndEventFormat override val textCommandErrorEventFormat: String get() = getCurrentResources().textCommandErrorEventFormat + + override val keyCommandStartEventFormat: String + get() = getCurrentResources().keyCommandStartEventFormat + override val keyCommandEndEventFormat: String + get() = getCurrentResources().keyCommandEndEventFormat + override val keyCommandErrorEventFormat: String + get() = getCurrentResources().keyCommandErrorEventFormat + override val screenshotCommandStartEventFormat: String get() = getCurrentResources().screenshotCommandStartEventFormat override val screenshotCommandEndEventFormat: String diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/EnglishResources.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/EnglishResources.kt index 80cb08e4..64d81f8f 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/EnglishResources.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/EnglishResources.kt @@ -12,6 +12,7 @@ object EnglishResources : StringResources { override val execute = "Run" override val save = "Save" override val delete = "Delete" + override val tab = "Tab" override val send = "Send" override val cancel = "Cancel" override val targetDevice = "Devices" @@ -65,6 +66,10 @@ object EnglishResources : StringResources { override val textCommandEndEventFormat = "End sending text「%s」" override val textCommandErrorEventFormat = "Error sending text「%s」" + override val keyCommandStartEventFormat = "Start sending key「%s」" + override val keyCommandEndEventFormat = "End sending key「%s」" + override val keyCommandErrorEventFormat = "Error sending key「%s」" + override val screenshotCommandStartEventFormat = "Start taking screenshot" override val screenshotCommandEndEventFormat = "End taking screenshot" override val screenshotCommandErrorEventFormat = "Error taking screenshot" diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/JapaneseResources.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/JapaneseResources.kt index dc35781a..8960d59e 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/JapaneseResources.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/JapaneseResources.kt @@ -12,6 +12,7 @@ object JapaneseResources : StringResources { override val execute = "実行" override val save = "保存" override val delete = "削除" + override val tab = "Tab" override val send = "送信" override val cancel = "キャンセル" override val targetDevice = "端末" @@ -65,6 +66,10 @@ object JapaneseResources : StringResources { override val textCommandEndEventFormat = "「%s」のテキスト送信が完了しました" override val textCommandErrorEventFormat = "「%s」のテキスト送信に失敗しました" + override val keyCommandStartEventFormat = "「%s」のキー送信を開始しました" + override val keyCommandEndEventFormat = "「%s」のキー送信が完了しました" + override val keyCommandErrorEventFormat = "「%s」のキー送信に失敗しました" + override val screenshotCommandStartEventFormat = "スクリーンショットの撮影を開始しました" override val screenshotCommandEndEventFormat = "スクリーンショットの撮影が完了しました" override val screenshotCommandErrorEventFormat = "スクリーンショットの撮影に失敗しました" diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/StringResources.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/StringResources.kt index 3b97f1e2..9c812418 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/StringResources.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/language/resources/StringResources.kt @@ -11,6 +11,7 @@ interface StringResources { val execute: String val save: String val delete: String + val tab: String val send: String val cancel: String val targetDevice: String @@ -64,6 +65,10 @@ interface StringResources { val textCommandEndEventFormat: String val textCommandErrorEventFormat: String + val keyCommandStartEventFormat: String + val keyCommandEndEventFormat: String + val keyCommandErrorEventFormat: String + val screenshotCommandStartEventFormat: String val screenshotCommandEndEventFormat: String val screenshotCommandErrorEventFormat: String diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/log/Event.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/log/Event.kt index 5195f05a..5d6b6d0b 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/log/Event.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/model/log/Event.kt @@ -54,6 +54,30 @@ interface Event { get() = Level.ERROR } + data class StartSendKeyCommand(val code: Int) : Event { + override val message: String + get() = String.format(Language.keyCommandStartEventFormat, code.toString()) + + override val level: Level + get() = Level.INFO + } + + data class EndSendKeyCommand(val code: Int) : Event { + override val message: String + get() = String.format(Language.keyCommandEndEventFormat, code.toString()) + + override val level: Level + get() = Level.INFO + } + + data class ErrorSendKeyCommand(val code: Int) : Event { + override val message: String + get() = String.format(Language.keyCommandErrorEventFormat, code.toString()) + + override val level: Level + get() = Level.ERROR + } + object StartSendScreenshotCommand : Event { override val message: String get() = Language.screenshotCommandStartEventFormat diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/repository/KeyCommandRepository.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/repository/KeyCommandRepository.kt new file mode 100644 index 00000000..24bd63ad --- /dev/null +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/repository/KeyCommandRepository.kt @@ -0,0 +1,13 @@ +package jp.kaleidot725.adbpad.domain.repository + +import jp.kaleidot725.adbpad.domain.model.device.Device + +interface KeyCommandRepository { + suspend fun sendKeyCommand( + device: Device, + keycode: Int, + onStart: suspend () -> Unit, + onComplete: suspend () -> Unit, + onFailed: suspend () -> Unit, + ) +} diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/SendTabCommandUseCase.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/SendTabCommandUseCase.kt new file mode 100644 index 00000000..49ccffc2 --- /dev/null +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/domain/usecase/text/SendTabCommandUseCase.kt @@ -0,0 +1,36 @@ +package jp.kaleidot725.adbpad.domain.usecase.text + +import jp.kaleidot725.adbpad.domain.model.device.Device +import jp.kaleidot725.adbpad.domain.model.log.Event +import jp.kaleidot725.adbpad.domain.repository.EventRepository +import jp.kaleidot725.adbpad.domain.repository.KeyCommandRepository + +class SendTabCommandUseCase( + private val eventRepository: EventRepository, + private val keyCommandRepository: KeyCommandRepository, +) { + suspend operator fun invoke( + device: Device, + onStart: suspend () -> Unit, + onFailed: suspend () -> Unit, + onComplete: suspend () -> Unit, + ) { + val tabKeyCode = 61 + keyCommandRepository.sendKeyCommand( + device = device, + keycode = tabKeyCode, + onStart = { + eventRepository.sendEvent(Event.StartSendKeyCommand(tabKeyCode)) + onStart() + }, + onFailed = { + eventRepository.sendEvent(Event.ErrorSendKeyCommand(tabKeyCode)) + onFailed() + }, + onComplete = { + eventRepository.sendEvent(Event.EndSendKeyCommand(tabKeyCode)) + onComplete() + }, + ) + } +} diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/di/RepositoryModule.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/di/RepositoryModule.kt index 0ccc159f..529b1d4c 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/di/RepositoryModule.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/di/RepositoryModule.kt @@ -2,12 +2,14 @@ package jp.kaleidot725.adbpad.repository.di import jp.kaleidot725.adbpad.domain.repository.DeviceRepository import jp.kaleidot725.adbpad.domain.repository.EventRepository +import jp.kaleidot725.adbpad.domain.repository.KeyCommandRepository import jp.kaleidot725.adbpad.domain.repository.NormalCommandRepository import jp.kaleidot725.adbpad.domain.repository.ScreenshotCommandRepository import jp.kaleidot725.adbpad.domain.repository.SettingRepository import jp.kaleidot725.adbpad.domain.repository.TextCommandRepository import jp.kaleidot725.adbpad.repository.impl.DeviceRepositoryImpl import jp.kaleidot725.adbpad.repository.impl.EventRepositoryImpl +import jp.kaleidot725.adbpad.repository.impl.KeyCommandRepositoryImpl import jp.kaleidot725.adbpad.repository.impl.NormalCommandRepositoryImpl import jp.kaleidot725.adbpad.repository.impl.ScreenshotCommandRepositoryImpl import jp.kaleidot725.adbpad.repository.impl.SettingRepositoryImpl @@ -38,4 +40,7 @@ val repositoryModule = factory { VersionRepository() } + factory { + KeyCommandRepositoryImpl() + } } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/impl/KeyCommandRepositoryImpl.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/impl/KeyCommandRepositoryImpl.kt new file mode 100644 index 00000000..39d1bfe3 --- /dev/null +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/repository/impl/KeyCommandRepositoryImpl.kt @@ -0,0 +1,33 @@ +package jp.kaleidot725.adbpad.repository.impl + +import com.malinskiy.adam.AndroidDebugBridgeClientFactory +import jp.kaleidot725.adbpad.domain.model.command.KeyCommand +import jp.kaleidot725.adbpad.domain.model.device.Device +import jp.kaleidot725.adbpad.domain.repository.KeyCommandRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +class KeyCommandRepositoryImpl : KeyCommandRepository { + private val adbClient = AndroidDebugBridgeClientFactory().build() + + override suspend fun sendKeyCommand( + device: Device, + keycode: Int, + onStart: suspend () -> Unit, + onComplete: suspend () -> Unit, + onFailed: suspend () -> Unit, + ) { + withContext(Dispatchers.IO) { + val command = KeyCommand(keycode) + command.requests.forEach { request -> + val result = adbClient.execute(request, device.serial) + if (result.exitCode != 0) { + onFailed() + return@withContext + } + } + + onComplete() + } + } +} diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/component/language/LanguageDropButton.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/component/language/LanguageDropButton.kt index cf5f7e42..94ed10cc 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/component/language/LanguageDropButton.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/component/language/LanguageDropButton.kt @@ -1,13 +1,11 @@ package jp.kaleidot725.adbpad.view.component.language import androidx.compose.desktop.ui.tooling.preview.Preview -import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.DropdownMenu import androidx.compose.material.DropdownMenuItem import androidx.compose.material.Icon diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/component/text/InputTextActionMenu.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/component/text/InputTextActionMenu.kt index b31774b3..b8324bc9 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/component/text/InputTextActionMenu.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/component/text/InputTextActionMenu.kt @@ -22,6 +22,9 @@ fun InputTextActionMenu( onTextChange: (String) -> Unit, onSend: () -> Unit, isSending: Boolean, + canSendTab: Boolean, + onSendTab: () -> Unit, + isSendingTag: Boolean, canSend: Boolean, onSave: () -> Unit, canSave: Boolean, @@ -51,6 +54,22 @@ fun InputTextActionMenu( ) } + Button( + enabled = canSendTab, + onClick = { onSendTab() }, + modifier = Modifier.fillMaxHeight().width(85.dp), + ) { + when (isSendingTag) { + true -> RunningIndicator() + else -> { + Text( + text = Language.tab, + textAlign = TextAlign.Center, + ) + } + } + } + Button( enabled = canSend, onClick = { onSend() }, @@ -77,9 +96,12 @@ private fun InputTextActionMenu_Preview() { onSend = {}, isSending = false, canSend = true, + canSendTab = false, + onSendTab = {}, onSave = {}, canSave = true, onTextChange = {}, + isSendingTag = false, modifier = Modifier.height(50.dp), ) } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/di/StateHolderModule.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/di/StateHolderModule.kt index 4ce23374..708c7a6f 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/di/StateHolderModule.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/di/StateHolderModule.kt @@ -27,6 +27,7 @@ val stateHolderModule = executeTextCommandUseCase = get(), getSelectedDeviceFlowUseCase = get(), sendUserInputTextCommandUseCase = get(), + sendTabCommandUseCase = get(), ) } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/screen/text/TextCommandScreen.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/screen/text/TextCommandScreen.kt index 10311a83..a36e0a4a 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/screen/text/TextCommandScreen.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/screen/text/TextCommandScreen.kt @@ -24,6 +24,9 @@ fun TextCommandScreen( canSendInputText: Boolean, onSaveInputText: () -> Unit, canSaveInputText: Boolean, + canSendTabKey: Boolean, + onSendTabKey: () -> Unit, + isSendingTab: Boolean, // Commands commands: List, onSendCommand: (TextCommand) -> Unit, @@ -45,6 +48,9 @@ fun TextCommandScreen( isSending = isSendingInputText, onSend = onSendInputText, canSend = canSendInputText, + onSendTab = onSendTabKey, + isSendingTag = isSendingTab, + canSendTab = canSendTabKey, onSave = onSaveInputText, canSave = canSaveInputText, modifier = Modifier.height(50.dp).fillMaxWidth().align(Alignment.BottomEnd), @@ -64,8 +70,11 @@ private fun InputTextScreen_Preview() { canSaveInputText = true, commands = listOf(TextCommand("TEST1"), TextCommand("TEST2")), onSendCommand = {}, + isSendingTab = false, canSendCommand = true, canSendInputText = true, onDeleteCommand = {}, + canSendTabKey = false, + onSendTabKey = {}, ) } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/screen/text/TextCommandState.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/screen/text/TextCommandState.kt index 039ee04a..7c2f36f0 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/screen/text/TextCommandState.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/screen/text/TextCommandState.kt @@ -8,8 +8,10 @@ data class TextCommandState( val userInputText: String = "", val isSendingUserInputText: Boolean = false, val selectedDevice: Device? = null, + val isSendingTab: Boolean = false, ) { val canSendCommand: Boolean get() = selectedDevice != null val canSendInputText: Boolean get() = selectedDevice != null && userInputText.isNotEmpty() val canSaveInputText: Boolean get() = userInputText.isNotEmpty() + val canSendTabKey: Boolean get() = selectedDevice != null } diff --git a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/screen/text/TextCommandStateHolder.kt b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/screen/text/TextCommandStateHolder.kt index 5b5bbc90..5d43954c 100644 --- a/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/screen/text/TextCommandStateHolder.kt +++ b/src/jvmMain/kotlin/jp/kaleidot725/adbpad/view/screen/text/TextCommandStateHolder.kt @@ -7,6 +7,7 @@ import jp.kaleidot725.adbpad.domain.usecase.text.AddTextCommandUseCase import jp.kaleidot725.adbpad.domain.usecase.text.DeleteTextCommandUseCase import jp.kaleidot725.adbpad.domain.usecase.text.ExecuteTextCommandUseCase import jp.kaleidot725.adbpad.domain.usecase.text.GetTextCommandUseCase +import jp.kaleidot725.adbpad.domain.usecase.text.SendTabCommandUseCase import jp.kaleidot725.adbpad.domain.usecase.text.SendUserInputTextCommandUseCase import jp.kaleidot725.adbpad.view.common.ChildStateHolder import kotlinx.coroutines.CoroutineScope @@ -26,12 +27,14 @@ class TextCommandStateHolder( private val getTextCommandUseCase: GetTextCommandUseCase, private val executeTextCommandUseCase: ExecuteTextCommandUseCase, private val sendUserInputTextCommandUseCase: SendUserInputTextCommandUseCase, + private val sendTabCommandUseCase: SendTabCommandUseCase, private val getSelectedDeviceFlowUseCase: GetSelectedDeviceFlowUseCase, ) : ChildStateHolder { private val coroutineScope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main + Dispatchers.IO) private val commands: MutableStateFlow> = MutableStateFlow(emptyList()) private val userInputText: MutableStateFlow = MutableStateFlow("") - private val isSendingUserInputText: MutableStateFlow = MutableStateFlow(false) + private val isSending: MutableStateFlow = MutableStateFlow(false) + private val isSendingTag: MutableStateFlow = MutableStateFlow(false) private val selectedDevice: StateFlow = getSelectedDeviceFlowUseCase() .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), null) @@ -40,10 +43,11 @@ class TextCommandStateHolder( combine( commands, userInputText, - isSendingUserInputText, + isSending, + isSendingTag, selectedDevice, - ) { inputTexts, userInputText, isSendingUserInputText, selectedDevice -> - TextCommandState(inputTexts, userInputText, isSendingUserInputText, selectedDevice) + ) { inputTexts, userInputText, isSending, isSendingTag, selectedDevice -> + TextCommandState(inputTexts, userInputText, isSending, selectedDevice, isSendingTag) }.stateIn(coroutineScope, SharingStarted.WhileSubscribed(), TextCommandState()) override fun setup() { @@ -65,7 +69,7 @@ class TextCommandStateHolder( if (isAscii) this.userInputText.value = text } - fun sendCommand(command: TextCommand) { + fun sendTextCommand(command: TextCommand) { val selectedDevice = state.value.selectedDevice ?: return coroutineScope.launch { executeTextCommandUseCase( @@ -84,9 +88,21 @@ class TextCommandStateHolder( sendUserInputTextCommandUseCase( device = selectedDevice, text = state.value.userInputText, - onStart = { isSendingUserInputText.value = true }, - onFailed = { isSendingUserInputText.value = false }, - onComplete = { isSendingUserInputText.value = false }, + onStart = { isSending.value = true }, + onFailed = { isSending.value = false }, + onComplete = { isSending.value = false }, + ) + } + } + + fun sendTabCommand() { + val selectedDevice = state.value.selectedDevice ?: return + coroutineScope.launch { + sendTabCommandUseCase( + device = selectedDevice, + onStart = { isSendingTag.value = true }, + onFailed = { isSendingTag.value = false }, + onComplete = { isSendingTag.value = false }, ) } }