mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2026-02-03 13:54:24 +01:00
Smooth transition on restarting session
This commit is contained in:
@@ -24,6 +24,9 @@ import androidx.compose.material3.OutlinedCard
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
@@ -41,6 +44,7 @@ import no.nordicsemi.android.toolbox.profile.data.ChannelSoundingServiceData
|
||||
import no.nordicsemi.android.toolbox.profile.data.ConfidenceLevel
|
||||
import no.nordicsemi.android.toolbox.profile.data.CsRangingData
|
||||
import no.nordicsemi.android.toolbox.profile.data.RangingSessionAction
|
||||
import no.nordicsemi.android.toolbox.profile.data.RangingSessionFailedReason
|
||||
import no.nordicsemi.android.toolbox.profile.data.RangingTechnology
|
||||
import no.nordicsemi.android.toolbox.profile.data.SessionClosedReason
|
||||
import no.nordicsemi.android.toolbox.profile.data.UpdateRate
|
||||
@@ -95,13 +99,14 @@ private fun ChannelSoundingView(
|
||||
channelSoundingState: ChannelSoundingServiceData,
|
||||
onClickEvent: (ChannelSoundingEvent) -> Unit,
|
||||
) {
|
||||
var isRestartingSession by rememberSaveable { mutableStateOf(false) }
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
when (val sessionData = channelSoundingState.rangingSessionAction) {
|
||||
is RangingSessionAction.OnError -> {
|
||||
SessionError(sessionData) { onClickEvent(it) }
|
||||
SessionError(sessionData, isRestartingSession) { onClickEvent(it) }
|
||||
}
|
||||
|
||||
is RangingSessionAction.OnResult -> {
|
||||
@@ -109,18 +114,26 @@ private fun ChannelSoundingView(
|
||||
channelSoundingState.updateRate,
|
||||
sessionData.data,
|
||||
sessionData.previousData,
|
||||
onClickEvent
|
||||
)
|
||||
) {
|
||||
isRestartingSession = true
|
||||
onClickEvent(it)
|
||||
}
|
||||
}
|
||||
|
||||
RangingSessionAction.OnClosed -> {
|
||||
SessionClosed(onClickEvent)
|
||||
SessionClosed(isRestartingSession, onClickEvent)
|
||||
}
|
||||
|
||||
RangingSessionAction.OnStart -> {
|
||||
isRestartingSession = false
|
||||
InitiatingSession()
|
||||
}
|
||||
|
||||
RangingSessionAction.OnRestarting -> {
|
||||
isRestartingSession = true
|
||||
RestartingSession()
|
||||
}
|
||||
|
||||
null -> LoadingView()
|
||||
}
|
||||
|
||||
@@ -149,8 +162,31 @@ private fun InitiatingSession() {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RestartingSession() {
|
||||
ScreenSection(modifier = Modifier.padding(0.dp) /* No padding */) {
|
||||
Column(modifier = Modifier.padding(top = 16.dp, start = 16.dp, end = 16.dp)) {
|
||||
SectionTitle(
|
||||
icon = Icons.Default.SocialDistance,
|
||||
title = stringResource(R.string.channel_sounding),
|
||||
)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
TextWithAnimatedDots(
|
||||
text = stringResource(R.string.ranging_session_restarting),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SessionClosed(
|
||||
isRestartingSession: Boolean,
|
||||
onClickEvent: (ChannelSoundingEvent) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
@@ -177,10 +213,17 @@ private fun SessionClosed(
|
||||
)
|
||||
}
|
||||
}
|
||||
Button(
|
||||
onClick = { onClickEvent(ChannelSoundingEvent.RestartRangingSession) },
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.reconnect))
|
||||
|
||||
if (isRestartingSession) {
|
||||
Button(onClick = { /* No action */ }) {
|
||||
Text(text = stringResource(id = R.string.ranging_session_reconnecting))
|
||||
}
|
||||
} else {
|
||||
Button(
|
||||
onClick = { onClickEvent(ChannelSoundingEvent.RestartRangingSession) },
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.reconnect))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,13 +232,14 @@ private fun SessionClosed(
|
||||
@Composable
|
||||
private fun SessionClosed_Preview() {
|
||||
NordicTheme {
|
||||
SessionClosed(onClickEvent = {})
|
||||
SessionClosed(false, onClickEvent = {})
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SessionError(
|
||||
sessionData: RangingSessionAction.OnError,
|
||||
isRestartingSession: Boolean,
|
||||
onClickEvent: (ChannelSoundingEvent) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
@@ -222,7 +266,12 @@ private fun SessionError(
|
||||
)
|
||||
}
|
||||
}
|
||||
if (sessionData.reason != SessionClosedReason.NOT_SUPPORTED ||
|
||||
|
||||
if (isRestartingSession && sessionData.reason == RangingSessionFailedReason.LOCAL_REQUEST) {
|
||||
Button(onClick = { /* No action */ }) {
|
||||
Text(text = stringResource(id = R.string.ranging_session_reconnecting))
|
||||
}
|
||||
} else if (sessionData.reason != SessionClosedReason.NOT_SUPPORTED ||
|
||||
sessionData.reason != SessionClosedReason.RANGING_NOT_AVAILABLE
|
||||
) {
|
||||
Button(
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
<string name="channel_sounding_not_supported">Channel Sounding is not supported on this Android version.</string>
|
||||
<string name="initiating_ranging">Initiating ranging</string>
|
||||
<string name="ranging_session_restarting">Reconnecting session</string>
|
||||
<string name="ranging_session_stopped">Ranging session stopped</string>
|
||||
<string name="ranging_session_reconnecting">Reconnecting…</string>
|
||||
|
||||
<string name="ranging_distance">Distance</string>
|
||||
<string name="current_measurement">Current measurement</string>
|
||||
|
||||
@@ -10,7 +10,7 @@ data class ChannelSoundingServiceData(
|
||||
) : ProfileServiceData()
|
||||
|
||||
sealed interface RangingSessionAction {
|
||||
object OnStart : RangingSessionAction
|
||||
data object OnStart : RangingSessionAction
|
||||
data class OnResult(
|
||||
val data: CsRangingData,
|
||||
val previousData: List<Float> = emptyList()
|
||||
@@ -18,6 +18,7 @@ sealed interface RangingSessionAction {
|
||||
|
||||
data class OnError(val reason: SessionCloseReasonProvider) : RangingSessionAction
|
||||
object OnClosed : RangingSessionAction
|
||||
data object OnRestarting : RangingSessionAction
|
||||
}
|
||||
|
||||
data class CsRangingData(
|
||||
|
||||
Reference in New Issue
Block a user