Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.CompositionLocalProvider
import androidx.wear.compose.foundation.LocalAmbientModeManager
import androidx.wear.compose.foundation.rememberAmbientModeManager
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.fragment.app.FragmentActivity
import androidx.navigation.NavHostController
Expand Down Expand Up @@ -58,16 +61,20 @@ class MainActivity : FragmentActivity() {
requestPermissions.launch(PreparingViewModel.permissions.toTypedArray())

setContent {
navController = rememberSwipeDismissableNavController()
val ambientModeManager = rememberAmbientModeManager()

ExerciseSampleApp(
navController,
onFinishActivity = { this.finish() }
)
CompositionLocalProvider(LocalAmbientModeManager provides ambientModeManager) {
navController = rememberSwipeDismissableNavController()

LaunchedEffect(Unit) {
prepareIfNoExercise()
pendingNavigation = false
ExerciseSampleApp(
navController,
onFinishActivity = { this.finish() }
)

LaunchedEffect(Unit) {
prepareIfNoExercise()
pendingNavigation = false
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.withSaveLayer
import com.google.android.horologist.compose.ambient.AmbientState


/**
* A Paint object configured to apply a grayscale effect.
Expand All @@ -47,18 +47,18 @@ private val grayscale =
/**
* Applies a grayscale effect and scales down the content when in ambient mode.
*
* This modifier checks the provided [AmbientState] to determine if the device is
* This modifier checks the provided [isAmbient] to determine if the device is
* in ambient mode. If it is, the content is scaled down by 10% and a grayscale
* filter is applied. When not in ambient mode, the content is rendered normally.
*/
fun Modifier.ambientGray(ambientState: AmbientState): Modifier =
fun Modifier.ambientGray(isAmbient: Boolean): Modifier =
graphicsLayer {
if (ambientState.isAmbient) {
if (isAmbient) {
scaleX = 0.9f
scaleY = 0.9f
}
}.drawWithContent {
if (ambientState.isAmbient) {
if (isAmbient) {
drawIntoCanvas {
it.withSaveLayer(size.toRect(), grayscale) {
drawContent()
Expand All @@ -70,14 +70,14 @@ fun Modifier.ambientGray(ambientState: AmbientState): Modifier =
}

/**
* This modifier conditionally draws the content based on the state provided by an [AmbientState].
* This modifier conditionally draws the content based on whether it is in ambient mode.
*
* If the `isInteractive` property of the provided [ambientState] is true, the content will be drawn.
* If [isAmbient] is false, the content will be drawn.
* Otherwise, the content will not be drawn, effectively leaving the area blank.
*/
fun Modifier.ambientBlank(ambientState: AmbientState): Modifier =
fun Modifier.ambientBlank(isAmbient: Boolean): Modifier =
drawWithContent {
if (ambientState.isInteractive) {
if (!isAmbient) {
drawContent()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.wear.compose.foundation.AmbientMode
import androidx.wear.compose.foundation.LocalAmbientModeManager
import androidx.wear.compose.foundation.pager.HorizontalPager
import androidx.wear.compose.foundation.pager.rememberPagerState
import androidx.wear.compose.material3.AlertDialog
Expand All @@ -49,7 +51,7 @@ import androidx.wear.compose.material3.Text
import androidx.wear.compose.ui.tooling.preview.WearPreviewDevices
import com.example.exercisesamplecompose.R
import com.example.exercisesamplecompose.data.ServiceState
import com.example.exercisesamplecompose.presentation.ambient.ambientBlank
import com.example.exercisesamplecompose.presentation.ambient.ambientGray
import com.example.exercisesamplecompose.presentation.component.CaloriesText
import com.example.exercisesamplecompose.presentation.component.DistanceText
import com.example.exercisesamplecompose.presentation.component.HRText
Expand All @@ -63,8 +65,6 @@ import com.example.exercisesamplecompose.presentation.summary.SummaryScreenState
import com.example.exercisesamplecompose.presentation.theme.ThemePreview
import com.example.exercisesamplecompose.service.ExerciseServiceState
import com.google.android.horologist.annotations.ExperimentalHorologistApi
import com.google.android.horologist.compose.ambient.AmbientAware
import com.google.android.horologist.compose.ambient.AmbientState
import com.google.android.horologist.health.composables.ActiveDurationText
import kotlinx.coroutines.launch

Expand All @@ -91,17 +91,17 @@ fun ExerciseRoute(
uiState = uiState
)
} else {
AmbientAware { ambientState ->
ExerciseScreen(
ambientState = ambientState,
onPauseClick = { viewModel.pauseExercise() },
onEndClick = { viewModel.endExercise() },
onResumeClick = { viewModel.resumeExercise() },
onStartClick = { viewModel.startExercise() },
uiState = uiState,
modifier = modifier
)
}
val isAmbient = LocalAmbientModeManager.current?.currentAmbientMode is AmbientMode.Ambient

ExerciseScreen(
isAmbient = isAmbient,
onPauseClick = { viewModel.pauseExercise() },
onEndClick = { viewModel.endExercise() },
onResumeClick = { viewModel.resumeExercise() },
onStartClick = { viewModel.startExercise() },
uiState = uiState,
modifier = modifier
)
Comment thread
kul3r4 marked this conversation as resolved.
}
}

Expand Down Expand Up @@ -149,7 +149,7 @@ fun ErrorStartingExerciseScreen(
*/
@Composable
fun ExerciseScreen(
ambientState: AmbientState,
isAmbient: Boolean,
onPauseClick: () -> Unit,
onEndClick: () -> Unit,
onResumeClick: () -> Unit,
Expand All @@ -165,7 +165,7 @@ fun ExerciseScreen(
HorizontalPager(
state = pagerState
) { page ->
ScreenScaffold {
ScreenScaffold(modifier = Modifier.ambientGray(isAmbient)) {
if (page == 0) {
ExerciseControlButtons(
uiState = uiState,
Expand Down Expand Up @@ -320,6 +320,7 @@ private fun DurationRow(uiState: ExerciseScreenState) {
fun ExerciseScreenPreview() {
ThemePreview {
ExerciseScreen(
isAmbient = false,
onPauseClick = {},
onEndClick = {},
onResumeClick = {},
Expand All @@ -331,8 +332,7 @@ fun ExerciseScreenPreview() {
ExerciseServiceState()
),
exerciseState = ExerciseServiceState()
),
ambientState = AmbientState.Interactive
)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ 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.google.android.horologist.compose.ambient.AmbientAware
import com.google.android.horologist.compose.ambient.AmbientState
import androidx.wear.compose.foundation.AmbientMode
import androidx.wear.compose.foundation.LocalAmbientModeManager
import com.google.android.horologist.compose.layout.ColumnItemType
import com.google.android.horologist.compose.layout.rememberResponsiveColumnPadding

Expand Down Expand Up @@ -105,17 +105,17 @@ fun PreparingExerciseRoute(
}
}

AmbientAware { ambientState ->
PreparingExerciseScreen(
onStart = {
viewModel.startExercise()
onStart()
},
uiState = uiState,
onGoals = { onGoals() },
ambientState = ambientState
)
}
val isAmbient = LocalAmbientModeManager.current?.currentAmbientMode is AmbientMode.Ambient

PreparingExerciseScreen(
onStart = {
viewModel.startExercise()
onStart()
},
uiState = uiState,
onGoals = { onGoals() },
isAmbient = isAmbient
)

if (uiState.isTrackingInAnotherApp) {
var dismissed by remember { mutableStateOf(false) }
Expand All @@ -133,7 +133,7 @@ fun PreparingExerciseRoute(
@Composable
fun PreparingExerciseScreen(
uiState: PreparingScreenState,
ambientState: AmbientState,
isAmbient: Boolean,
onStart: () -> Unit = {},
onGoals: () -> Unit = {}
) {
Expand All @@ -149,7 +149,7 @@ fun PreparingExerciseScreen(
timeText = {},
contentPadding = contentPadding,
modifier = Modifier
.ambientGray(ambientState)
.ambientGray(isAmbient)
) { contentPadding ->
LocationStatusText(
updatePrepareLocationStatus(
Expand Down Expand Up @@ -247,7 +247,7 @@ fun PreparingExerciseScreenPreview() {
requiredPermissions = PreparingViewModel.permissions,
hasExerciseCapabilities = true
),
ambientState = AmbientState.Interactive
isAmbient = false
)
}
}
Expand All @@ -265,7 +265,7 @@ fun PreparingExerciseScreenPreviewAmbient() {
requiredPermissions = PreparingViewModel.permissions,
hasExerciseCapabilities = true
),
ambientState = AmbientState.Ambient()
isAmbient = true
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@
*/
package com.example.exercisesamplecompose.presentation

import androidx.compose.runtime.CompositionLocalProvider

import androidx.wear.compose.material3.AppScaffold
import com.example.exercisesamplecompose.data.ServiceState
import com.example.exercisesamplecompose.presentation.exercise.ExerciseScreen
import com.example.exercisesamplecompose.presentation.exercise.ExerciseScreenState
import com.example.exercisesamplecompose.service.ExerciseServiceState
import com.google.android.horologist.compose.ambient.AmbientState
import com.google.android.horologist.compose.ambient.LocalAmbientState

import com.google.android.horologist.compose.layout.ResponsiveTimeText
import com.google.android.horologist.screenshots.FixedTimeSource
import com.google.android.horologist.screenshots.rng.WearDevice
Expand Down Expand Up @@ -55,7 +54,7 @@ class ExerciseScreenTest(
timeText = { ResponsiveTimeText(timeSource = FixedTimeSource) }
) {
ExerciseScreen(
ambientState = AmbientState.Interactive,
isAmbient = false,
onPauseClick = {},
onEndClick = {},
onResumeClick = {},
Expand All @@ -80,28 +79,26 @@ class ExerciseScreenTest(
// Only run for one variant
Assume.assumeTrue(device == WearDevice.GooglePixelWatch)

CompositionLocalProvider(LocalAmbientState provides AmbientState.Ambient()) {
AppScaffold(
timeText = { ResponsiveTimeText(timeSource = FixedTimeSource) }
) {
ExerciseScreen(
onPauseClick = {},
onEndClick = {},
onResumeClick = {},
onStartClick = {},
uiState =
ExerciseScreenState(
hasExerciseCapabilities = true,
isTrackingAnotherExercise = false,
serviceState =
ServiceState.Connected(
ExerciseServiceState()
),
exerciseState = ExerciseServiceState()
AppScaffold(
timeText = { ResponsiveTimeText(timeSource = FixedTimeSource) }
) {
ExerciseScreen(
isAmbient = true,
onPauseClick = {},
onEndClick = {},
onResumeClick = {},
onStartClick = {},
uiState =
ExerciseScreenState(
hasExerciseCapabilities = true,
isTrackingAnotherExercise = false,
serviceState =
ServiceState.Connected(
ExerciseServiceState()
),
ambientState = AmbientState.Ambient()
exerciseState = ExerciseServiceState()
)
}
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import com.example.exercisesamplecompose.presentation.preparing.PreparingExercis
import com.example.exercisesamplecompose.presentation.preparing.PreparingScreenState
import com.example.exercisesamplecompose.presentation.preparing.PreparingViewModel
import com.example.exercisesamplecompose.service.ExerciseServiceState
import com.google.android.horologist.compose.ambient.AmbientState

import com.google.android.horologist.screenshots.rng.WearDevice
import com.google.android.horologist.screenshots.rng.WearDeviceScreenshotTest
import org.junit.Assume
Expand Down Expand Up @@ -71,7 +71,7 @@ class PreparingExerciseScreenTest(
requiredPermissions = PreparingViewModel.permissions,
hasExerciseCapabilities = true
),
ambientState = AmbientState.Interactive
isAmbient = false
)
}
}
Expand All @@ -94,7 +94,7 @@ class PreparingExerciseScreenTest(
requiredPermissions = PreparingViewModel.permissions,
hasExerciseCapabilities = true
),
ambientState = AmbientState.Ambient()
isAmbient = true
)
}
}
Expand Down
Loading
Loading