diff --git a/CHANGELOG.md b/CHANGELOG.md index e9c6926046..df566b5310 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Attention: don't forget to add the flag for F-Droid before release - [Feature] Add How to Use dialog into remote-controls - [Feature] Skip infrared signals on setup screen - [Feature] Better user-ux when configuring remote control +- [Feature] Navigate to previous setup item on remote controls - [Feature] Add flipper action dialogs into remote control and move it into bottombar - [Feature] Add new icons for remote-controls - [Refactor] Load RemoteControls from flipper, emulating animation diff --git a/components/remote-controls/setup/impl/src/main/kotlin/com/flipperdevices/remotecontrols/impl/setup/presentation/decompose/internal/SetupComponentImpl.kt b/components/remote-controls/setup/impl/src/main/kotlin/com/flipperdevices/remotecontrols/impl/setup/presentation/decompose/internal/SetupComponentImpl.kt index 1ab37962f4..8b7ca506bd 100644 --- a/components/remote-controls/setup/impl/src/main/kotlin/com/flipperdevices/remotecontrols/impl/setup/presentation/decompose/internal/SetupComponentImpl.kt +++ b/components/remote-controls/setup/impl/src/main/kotlin/com/flipperdevices/remotecontrols/impl/setup/presentation/decompose/internal/SetupComponentImpl.kt @@ -1,6 +1,7 @@ package com.flipperdevices.remotecontrols.impl.setup.presentation.decompose.internal import com.arkivanov.decompose.ComponentContext +import com.arkivanov.essenty.backhandler.BackCallback import com.arkivanov.essenty.instancekeeper.getOrCreate import com.flipperdevices.bridge.dao.api.model.FlipperFilePath import com.flipperdevices.bridge.dao.api.model.FlipperKeyType @@ -137,10 +138,11 @@ class SetupComponentImpl @AssistedInject constructor( override fun tryLoad() { if (dispatchSignalApi.state.value is DispatchSignalApi.State.Emulating) return dispatchSignalApi.reset() + val historyData = historyViewModel.data createCurrentSignalViewModel.load( - successResults = historyViewModel.state.value.successfulSignals, - failedResults = historyViewModel.state.value.failedSignals, - skippedResults = historyViewModel.state.value.skippedSignals + successResults = historyData.successfulSignals, + failedResults = historyData.failedSignals, + skippedResults = historyData.skippedSignals ) _lastEmulatedSignal.value = null } @@ -202,7 +204,20 @@ class SetupComponentImpl @AssistedInject constructor( ) } - override fun onBackClick() = onBackClick.invoke() + private val backCallback = BackCallback(true) { + if (historyViewModel.isEmpty) { + onBackClick.invoke() + } else { + historyViewModel.forgetLast() + } + tryLoad() + } + + override fun onBackClick() = backCallback.onBack() + + init { + backHandler.register(backCallback) + } } private val ABSOLUTE_TEMP_FOLDER_PATH = "/${FlipperKeyType.INFRARED.flipperDir}/temp" diff --git a/components/remote-controls/setup/impl/src/main/kotlin/com/flipperdevices/remotecontrols/impl/setup/presentation/viewmodel/HistoryViewModel.kt b/components/remote-controls/setup/impl/src/main/kotlin/com/flipperdevices/remotecontrols/impl/setup/presentation/viewmodel/HistoryViewModel.kt index fb2798ea54..57ef0a1c5d 100644 --- a/components/remote-controls/setup/impl/src/main/kotlin/com/flipperdevices/remotecontrols/impl/setup/presentation/viewmodel/HistoryViewModel.kt +++ b/components/remote-controls/setup/impl/src/main/kotlin/com/flipperdevices/remotecontrols/impl/setup/presentation/viewmodel/HistoryViewModel.kt @@ -3,34 +3,49 @@ package com.flipperdevices.remotecontrols.impl.setup.presentation.viewmodel import com.flipperdevices.core.ui.lifecycle.DecomposeViewModel import com.flipperdevices.ifrmvp.backend.model.SignalModel import com.flipperdevices.ifrmvp.backend.model.SignalRequestModel.SignalResultData -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.update import javax.inject.Inject class HistoryViewModel @Inject constructor() : DecomposeViewModel() { - private val _state = MutableStateFlow(State()) - val state = _state.asStateFlow() + private val flatData = mutableListOf() + + val data: State + get() = State( + successfulSignals = flatData + .filter { it.type == FlatData.FlatDataType.SUCCESS } + .map(FlatData::data), + failedSignals = flatData + .filter { it.type == FlatData.FlatDataType.FAILED } + .map(FlatData::data), + skippedSignals = flatData + .filter { it.type == FlatData.FlatDataType.SKIPPED } + .map(FlatData::data), + ) + val isEmpty: Boolean + get() = flatData.isEmpty() + + fun forgetLast() { + flatData.removeLast() + } fun rememberSuccessful(signalModel: SignalModel) { val signalResultData = SignalResultData( signalId = signalModel.id, ) - _state.update { it.copy(successfulSignals = it.successfulSignals + signalResultData) } + flatData += FlatData(signalResultData, FlatData.FlatDataType.SUCCESS) } fun rememberFailed(signalModel: SignalModel) { val signalResultData = SignalResultData( signalId = signalModel.id, ) - _state.update { it.copy(failedSignals = it.failedSignals + signalResultData) } + flatData += FlatData(signalResultData, FlatData.FlatDataType.FAILED) } fun rememberSkipped(signalModel: SignalModel) { val signalResultData = SignalResultData( signalId = signalModel.id, ) - _state.update { it.copy(skippedSignals = it.skippedSignals + signalResultData) } + flatData += FlatData(signalResultData, FlatData.FlatDataType.SKIPPED) } data class State( @@ -38,4 +53,13 @@ class HistoryViewModel @Inject constructor() : DecomposeViewModel() { val failedSignals: List = emptyList(), val skippedSignals: List = emptyList() ) + + class FlatData( + val data: SignalResultData, + val type: FlatDataType + ) { + enum class FlatDataType { + SUCCESS, FAILED, SKIPPED + } + } }