Skip to content

Commit

Permalink
Fix expandable signal verify (#892)
Browse files Browse the repository at this point in the history
**Background**

When selecting signal inside Infrared remote setup - the "bottom sheet"
displayed from the beginning. It should be displayed only when signal is
dispatched.

**Changes**

- Add state to display "bottom sheet" only after signal is dispatched

**Test plan**

- Open signal select screen
- Press signal
- See the confirm menu animated and shown only after signal is
dispatched
- Press yes/no
- See "bottom sheet" is hidden again
  • Loading branch information
makeevrserg authored Jul 15, 2024
1 parent f793f8d commit bdfdf6e
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [FIX] Button arrow tint
- [FIX] Paddings for update button
- [FIX] Crash on app startup with WearOS app
- [FIX] Expand verify signal bottom sheet only after signal is dispatched
- [CI] Add https://github.com/LionZXY/detekt-decompose-rule
- [CI] Enabling detekt module for android and kmp modules
- [CI] Bump target SDK to 34
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotlinx.coroutines.flow.StateFlow

interface DispatchSignalApi : InstanceKeeper.Instance {
val state: StateFlow<State>
val isEmulated: StateFlow<Boolean>

fun dismissBusyDialog()

Expand All @@ -17,6 +18,8 @@ interface DispatchSignalApi : InstanceKeeper.Instance {
*/
fun dispatch(config: EmulateConfig)

fun reset()

/**
* Dispatch specific key from custom located remote
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ fun SetupScreen(
}
LoadedContent(
model = model,
isEmulating = model.isEmulating,
modifier = Modifier.padding(scaffoldPaddings),
onPositiveClicked = setupComponent::onSuccessClicked,
onNegativeClicked = setupComponent::onFailedClicked,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.flipperdevices.remotecontrols.impl.setup.composable.components

import android.content.res.Configuration
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
Expand All @@ -18,36 +21,40 @@ import com.flipperdevices.remotecontrols.setup.impl.R as SetupR
@Composable
fun LoadedContent(
model: SetupComponent.Model.Loaded,
isEmulating: Boolean,
onPositiveClicked: () -> Unit,
onNegativeClicked: () -> Unit,
onDispatchSignalClicked: () -> Unit,
modifier: Modifier = Modifier
) {
val ifrFileModel = model.response.ifrFileModel
val signalResponse = model.response.signalResponse
Column(
modifier = modifier.fillMaxSize(),
verticalArrangement = Arrangement.SpaceBetween
) {
Box(modifier = modifier.fillMaxSize()) {
when {
ifrFileModel != null -> Unit

signalResponse != null -> {
Box(modifier = Modifier)
ButtonContent(
onClicked = onDispatchSignalClicked,
modifier = Modifier,
modifier = Modifier.align(Alignment.Center),
data = signalResponse.data,
categoryName = signalResponse.categoryName,
isEmulating = isEmulating
isEmulating = model.isEmulating,
)
ConfirmContent(
text = signalResponse.message,
onNegativeClicked = onNegativeClicked,
onPositiveClicked = onPositiveClicked,
AnimatedVisibility(
visible = model.isEmulated,
enter = slideInVertically(initialOffsetY = { it / 2 }),
exit = slideOutVertically(),
modifier = Modifier
)
.fillMaxWidth()
.align(Alignment.BottomCenter),
) {
ConfirmContent(
text = signalResponse.message,
onNegativeClicked = onNegativeClicked,
onPositiveClicked = onPositiveClicked,
modifier = Modifier.align(Alignment.BottomCenter)
)
}
}

else -> {
Expand All @@ -70,8 +77,8 @@ private fun LoadedContentPreview() {
LoadedContent(
model = SetupComponent.Model.Loaded(
response = SignalResponseModel(),
isEmulated = true
),
isEmulating = true,
onPositiveClicked = {},
onNegativeClicked = {},
onDispatchSignalClicked = {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ interface SetupComponent {
data class Loaded(
val response: SignalResponseModel,
val isFlipperBusy: Boolean = false,
val isEmulating: Boolean = false
val isEmulating: Boolean = false,
val isEmulated: Boolean
) : Model

data object Error : Model
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ class SetupComponentImpl @AssistedInject constructor(
createCurrentSignalViewModel.state,
saveSignalApi.state,
dispatchSignalApi.state,
transform = { signalState, saveState, dispatchState ->
dispatchSignalApi.isEmulated,
transform = { signalState, saveState, dispatchState, isEmulated ->
when (signalState) {
CurrentSignalViewModel.State.Error -> SetupComponent.Model.Error
is CurrentSignalViewModel.State.Loaded -> {
Expand All @@ -83,13 +84,15 @@ class SetupComponentImpl @AssistedInject constructor(
SaveTempSignalApi.State.Pending -> SetupComponent.Model.Loaded(
response = signalState.response,
isFlipperBusy = dispatchState is DispatchSignalApi.State.FlipperIsBusy,
isEmulating = dispatchState is DispatchSignalApi.State.Emulating
isEmulating = dispatchState is DispatchSignalApi.State.Emulating,
isEmulated = isEmulated
)

SaveTempSignalApi.State.Uploaded -> SetupComponent.Model.Loaded(
response = signalState.response,
isFlipperBusy = dispatchState is DispatchSignalApi.State.FlipperIsBusy,
isEmulating = dispatchState is DispatchSignalApi.State.Emulating
isEmulating = dispatchState is DispatchSignalApi.State.Emulating,
isEmulated = isEmulated
)

is SaveTempSignalApi.State.Uploading -> SetupComponent.Model.Loading(
Expand All @@ -115,6 +118,8 @@ class SetupComponentImpl @AssistedInject constructor(
}

override fun tryLoad() {
if (dispatchSignalApi.state.value is DispatchSignalApi.State.Emulating) return
dispatchSignalApi.reset()
createCurrentSignalViewModel.load(
successResults = historyViewModel.state.value.successfulSignals,
failedResults = historyViewModel.state.value.failedSignals
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.flipperdevices.remotecontrols.impl.setup.util.toByteArray
import com.squareup.anvil.annotations.ContributesBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
Expand All @@ -40,8 +41,20 @@ class DispatchSignalViewModel @Inject constructor(

private val _state = MutableStateFlow<DispatchSignalApi.State>(DispatchSignalApi.State.Pending)
override val state = _state.asStateFlow()

private val _isEmulated = MutableStateFlow(false)
override val isEmulated = _isEmulated.asStateFlow()

private var latestDispatchJob: Job? = null

override fun reset() {
viewModelScope.launch {
latestDispatchJob?.cancelAndJoin()
_state.value = DispatchSignalApi.State.Pending
_isEmulated.value = false
}
}

override fun dispatch(
identifier: IfrKeyIdentifier,
remotes: List<InfraredRemote>,
Expand Down Expand Up @@ -101,6 +114,7 @@ class DispatchSignalViewModel @Inject constructor(
delay(DEFAULT_SIGNAL_DELAY)
emulateHelper.stopEmulate(this, serviceApi.requestApi)
_state.emit(DispatchSignalApi.State.Pending)
_isEmulated.emit(true)
} catch (ignored: AlreadyOpenedAppException) {
_state.emit(DispatchSignalApi.State.FlipperIsBusy)
} catch (e: Exception) {
Expand Down

0 comments on commit bdfdf6e

Please sign in to comment.