Skip to content

Commit

Permalink
feat: adjust Ambient support for Exercise and Preparing screens
Browse files Browse the repository at this point in the history
This change adds Ambient support for the Exercise and Preparing screens:
- The Exercise screen now supports the Ambient state by displaying a blank screen when ambient.
- The Preparing screen now uses a gray background when ambient.
- Updates existing screenshot tests to cover ambient state.
  • Loading branch information
yschimke committed Dec 6, 2024
1 parent 24452e9 commit 2bb4f93
Show file tree
Hide file tree
Showing 22 changed files with 193 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import androidx.wear.compose.material.Text
import androidx.wear.compose.ui.tooling.preview.WearPreviewDevices
import com.example.exercisesamplecompose.R
import com.example.exercisesamplecompose.ambient.AmbientAware
import com.example.exercisesamplecompose.ambient.AmbientState
import com.example.exercisesamplecompose.data.ServiceState
import com.example.exercisesamplecompose.presentation.ambient.ambientBlank
import com.example.exercisesamplecompose.presentation.component.CaloriesText
Expand Down Expand Up @@ -84,14 +85,17 @@ fun ExerciseRoute(
onRestart = onRestart, onFinishActivity = onFinishActivity, uiState = uiState
)
} else {
ExerciseScreen(
onPauseClick = { viewModel.pauseExercise() },
onEndClick = { viewModel.endExercise() },
onResumeClick = { viewModel.resumeExercise() },
onStartClick = { viewModel.startExercise() },
uiState = uiState,
modifier = modifier
)
AmbientAware { ambientState ->
ExerciseScreen(
ambientState = ambientState,
onPauseClick = { viewModel.pauseExercise() },
onEndClick = { viewModel.endExercise() },
onResumeClick = { viewModel.resumeExercise() },
onStartClick = { viewModel.startExercise() },
uiState = uiState,
modifier = modifier
)
}
}
}

Expand Down Expand Up @@ -120,6 +124,7 @@ fun ErrorStartingExerciseScreen(
*/
@Composable
fun ExerciseScreen(
ambientState: AmbientState,
onPauseClick: () -> Unit,
onEndClick: () -> Unit,
onResumeClick: () -> Unit,
Expand All @@ -130,42 +135,40 @@ fun ExerciseScreen(
val coroutineScope = rememberCoroutineScope()
val pagerState = rememberPagerState(initialPage = 1, pageCount = { 2 })

AmbientAware { ambientState ->
// Workaround bug in modifier placement in PagerScreen
Box(
modifier = modifier.ambientBlank(ambientState)
) {
PagerScreen(
state = pagerState,
modifier = modifier
.fillMaxSize()
.padding(6.dp)
) { page ->
when (page) {
0 -> {
ExerciseControlButtons(
uiState = uiState,
onStartClick = onStartClick,
onEndClick = onEndClick,
onResumeClick = {
onResumeClick()
coroutineScope.launch {
pagerState.animateScrollToPage(1)
}
// Workaround bug in modifier placement in PagerScreen
Box(
modifier = modifier.ambientBlank(ambientState)
) {
PagerScreen(
state = pagerState,
modifier = modifier
.fillMaxSize()
.padding(6.dp)
) { page ->
when (page) {
0 -> {
ExerciseControlButtons(
uiState = uiState,
onStartClick = onStartClick,
onEndClick = onEndClick,
onResumeClick = {
onResumeClick()
coroutineScope.launch {
pagerState.animateScrollToPage(1)
}

},
onPauseClick = {
onPauseClick()
coroutineScope.launch {
pagerState.animateScrollToPage(1)
}
},
)
}
},
onPauseClick = {
onPauseClick()
coroutineScope.launch {
pagerState.animateScrollToPage(1)
}
},
)
}

1 -> {
ExerciseMetrics(uiState = uiState)
}
1 -> {
ExerciseMetrics(uiState = uiState)
}
}
}
Expand Down Expand Up @@ -311,6 +314,7 @@ fun ExerciseScreenPreview() {
),
exerciseState = ExerciseServiceState()
),
ambientState = AmbientState.Interactive,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ import androidx.wear.compose.material.curvedText
import androidx.wear.compose.ui.tooling.preview.WearPreviewDevices
import com.example.exercisesamplecompose.R
import com.example.exercisesamplecompose.ambient.AmbientAware
import com.example.exercisesamplecompose.ambient.AmbientState
import com.example.exercisesamplecompose.data.ServiceState
import com.example.exercisesamplecompose.presentation.ambient.ambientGray
import com.example.exercisesamplecompose.presentation.dialogs.ExerciseInProgressAlert
import com.example.exercisesamplecompose.presentation.theme.ThemePreview
import com.example.exercisesamplecompose.service.ExerciseServiceState
import com.example.exercisesamplecompose.presentation.ambient.ambientGray
import com.google.android.horologist.compose.layout.ScalingLazyColumn
import com.google.android.horologist.compose.layout.ScalingLazyColumnDefaults
import com.google.android.horologist.compose.layout.ScalingLazyColumnDefaults.ItemType
Expand Down Expand Up @@ -100,29 +101,24 @@ fun PreparingExerciseRoute(
}

AmbientAware { ambientState ->
Box(
modifier = Modifier
.fillMaxSize()
.ambientGray(ambientState)
) {
PreparingExerciseScreen(
onStart = {
viewModel.startExercise()
onStart()
},
uiState = uiState,
onGoals = { onGoals() }
)
PreparingExerciseScreen(
onStart = {
viewModel.startExercise()
onStart()
},
uiState = uiState,
onGoals = { onGoals() },
ambientState = ambientState,
)
}

if (uiState.isTrackingInAnotherApp) {
var dismissed by remember { mutableStateOf(false) }
ExerciseInProgressAlert(
onNegative = onFinishActivity,
onPositive = { dismissed = true },
showDialog = !dismissed
)
}
}
if (uiState.isTrackingInAnotherApp) {
var dismissed by remember { mutableStateOf(false) }
ExerciseInProgressAlert(
onNegative = onFinishActivity,
onPositive = { dismissed = true },
showDialog = !dismissed
)
}
}

Expand All @@ -131,8 +127,9 @@ fun PreparingExerciseRoute(
*/
@Composable
fun PreparingExerciseScreen(
onStart: () -> Unit = {},
uiState: PreparingScreenState,
ambientState: AmbientState,
onStart: () -> Unit = {},
onGoals: () -> Unit = {}
) {
val location = (uiState as? PreparingScreenState.Preparing)?.locationAvailability
Expand All @@ -142,55 +139,66 @@ fun PreparingExerciseScreen(
first = ItemType.Unspecified, last = ItemType.Unspecified
)
)
ScreenScaffold(scrollState = columnState, timeText = {}) {
LocationStatusText(updatePrepareLocationStatus(
locationAvailability = location ?: LocationAvailability.UNAVAILABLE
))
ScalingLazyColumn(
columnState = columnState
) {
item {
Text(
textAlign = TextAlign.Center,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
text = stringResource(id = R.string.preparing_exercise),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 0.15f * LocalConfiguration.current.screenWidthDp.dp)
)
}
item {

Column(
modifier = Modifier
.fillMaxWidth()
.padding(top = 6.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Button(
imageVector = Icons.Default.PlayArrow,
contentDescription = stringResource(id = R.string.start),
onClick = onStart,
buttonSize = ButtonSize.Small,
enabled = uiState is PreparingScreenState.Preparing
Box(
modifier = Modifier
.fillMaxSize()
.ambientGray(ambientState)
) {
ScreenScaffold(
scrollState = if (ambientState.isInteractive) columnState else null,
timeText = {}) {
LocationStatusText(
updatePrepareLocationStatus(
locationAvailability = location ?: LocationAvailability.UNAVAILABLE
)
)
ScalingLazyColumn(
columnState = columnState
) {
item {
Text(
textAlign = TextAlign.Center,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
text = stringResource(id = R.string.preparing_exercise),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 0.15f * LocalConfiguration.current.screenWidthDp.dp)
)
}
item {

Column(
modifier = Modifier
.fillMaxWidth()
.padding(top = 6.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Button(
imageVector = Icons.Default.PlayArrow,
contentDescription = stringResource(id = R.string.start),
onClick = onStart,
buttonSize = ButtonSize.Small,
enabled = uiState is PreparingScreenState.Preparing
)

}
}
}
item {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(top = 6.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
CompactChip(
label = stringResource(id = R.string.goal),
onClick = onGoals,
)
item {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(top = 6.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
CompactChip(
label = stringResource(id = R.string.goal),
onClick = onGoals,
)
}
}
}
}
Expand Down Expand Up @@ -233,7 +241,9 @@ fun PreparingExerciseScreenPreview() {
requiredPermissions = PreparingViewModel.permissions,
hasExerciseCapabilities = true
),
onGoals = {})
onGoals = {},
ambientState = AmbientState.Interactive
)
}
}

Expand All @@ -251,6 +261,8 @@ fun PreparingExerciseScreenPreviewAmbient() {
requiredPermissions = PreparingViewModel.permissions,
hasExerciseCapabilities = true
),
onGoals = {})
onGoals = {},
ambientState = AmbientState.Ambient()
)
}
}
Loading

0 comments on commit 2bb4f93

Please sign in to comment.