Skip to content

[Wear] Scroll again to the next session in onResume #375

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
@@ -0,0 +1,20 @@
package fr.paug.androidmakers.wear.ui.common

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable

@Composable
fun SaveableLaunchedEffect(
key: Any,
block: suspend () -> Unit
) {
val lastLaunchedKey = rememberSaveable { mutableStateOf<Any?>(null) }
if (lastLaunchedKey.value != key) {
lastLaunchedKey.value = key
LaunchedEffect(Unit) {
block()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.core.app.ActivityCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.navigation.NavType
import androidx.navigation.navArgument
import androidx.wear.compose.foundation.SwipeToDismissBoxState
Expand All @@ -39,6 +41,7 @@ import fr.paug.androidmakers.wear.ui.session.list.SessionListScreen
import fr.paug.androidmakers.wear.ui.settings.SettingsScreen
import fr.paug.androidmakers.wear.ui.signin.SignInScreen
import fr.paug.androidmakers.wear.ui.theme.AndroidMakersWearTheme
import kotlinx.coroutines.flow.map
import org.koin.androidx.compose.koinViewModel
import org.koin.core.parameter.parametersOf

Expand Down Expand Up @@ -86,6 +89,8 @@ fun WearApp(

AndroidMakersWearTheme {
AppScaffold {
val isResumed by LocalLifecycleOwner.current.lifecycle.currentStateFlow.map { it == Lifecycle.State.RESUMED }
.collectAsState(false)
SwipeDismissableNavHost(
navController = navController,
startDestination = Navigation.main,
Expand All @@ -94,6 +99,7 @@ fun WearApp(
composable(Navigation.main) {
MainScreen(
viewModel = viewModel,
isResumed = isResumed,
swipeToDismissBoxState = swipeToDismissBoxState,
onSignInClick = onSignInClick,
onSignOutClick = { viewModel.signOut() },
Expand Down Expand Up @@ -125,6 +131,7 @@ fun WearApp(
@Composable
fun MainScreen(
viewModel: MainViewModel,
isResumed: Boolean,
swipeToDismissBoxState: SwipeToDismissBoxState,
onSignInClick: () -> Unit,
onSignOutClick: () -> Unit,
Expand All @@ -140,7 +147,8 @@ fun MainScreen(
modifier = Modifier
.fillMaxSize()
.edgeSwipeToDismiss(swipeToDismissBoxState),
state = pagerState
state = pagerState,
beyondViewportPageCount = 2,
) { page ->
when (page) {
0 -> {
Expand All @@ -156,6 +164,7 @@ fun MainScreen(
SessionListScreen(
sessions = sessionsDay1,
title = stringResource(id = R.string.main_day1),
isResumed = isResumed,
onSessionClick = onSessionClick
)
}
Expand All @@ -164,6 +173,7 @@ fun MainScreen(
SessionListScreen(
sessions = sessionsDay2,
title = stringResource(id = R.string.main_day2),
isResumed = isResumed,
onSessionClick = onSessionClick
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Bookmark
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
Expand Down Expand Up @@ -45,6 +44,7 @@ import com.google.android.horologist.compose.material.ResponsiveListHeader
import fr.paug.androidmakers.wear.R
import fr.paug.androidmakers.wear.ui.common.Loading
import fr.paug.androidmakers.wear.ui.common.PulsatingRedDot
import fr.paug.androidmakers.wear.ui.common.SaveableLaunchedEffect
import fr.paug.androidmakers.wear.ui.session.UISession
import fr.paug.androidmakers.wear.ui.session.uiSessions
import fr.paug.androidmakers.wear.ui.theme.amRed
Expand All @@ -53,6 +53,7 @@ import fr.paug.androidmakers.wear.ui.theme.amRed
fun SessionListScreen(
sessions: List<UISession>?,
title: String,
isResumed: Boolean,
onSessionClick: (String) -> Unit,
) {
if (sessions == null) {
Expand All @@ -61,6 +62,7 @@ fun SessionListScreen(
SessionList(
sessions = sessions,
title = title,
isResumed = isResumed,
onSessionClick = onSessionClick,
)
}
Expand All @@ -70,6 +72,7 @@ fun SessionListScreen(
private fun SessionList(
sessions: List<UISession>,
title: String,
isResumed: Boolean,
onSessionClick: (String) -> Unit,
) {
val columnState = rememberResponsiveColumnState(
Expand All @@ -79,13 +82,13 @@ private fun SessionList(
)
)

// Approximation of about half the height of a card, so the card is centered when scrolling to it.
// Maybe there's a way to get the actual height?
val scrollOffset = with(LocalDensity.current) { 80.dp.roundToPx() }

val nextSessionIndex = sessions.nextSessionIndex()
if (nextSessionIndex > 0) {
LaunchedEffect(Unit) {
val density = LocalDensity.current
SaveableLaunchedEffect(isResumed) {
val nextSessionIndex = sessions.nextSessionIndex()
if (nextSessionIndex > 0) {
// Approximation of about half the height of a card, so the card is centered when scrolling to it.
// Maybe there's a way to get the actual height?
val scrollOffset = with(density) { 80.dp.roundToPx() }
columnState.state.scrollToItem(
// Add 1 to the index to account for the title
index = nextSessionIndex + 1,
Expand Down Expand Up @@ -220,12 +223,12 @@ private fun SessionItem(
@WearPreviewFontScales
@Composable
private fun LoadingSessionListScreenPreview() {
SessionListScreen(null, stringResource(id = R.string.main_day1), {})
SessionListScreen(null, stringResource(id = R.string.main_day1), true, {})
}

@WearPreviewDevices
@WearPreviewFontScales
@Composable
private fun LoadedSessionListScreenPreview() {
SessionListScreen(uiSessions, stringResource(id = R.string.main_day1), {})
SessionListScreen(uiSessions, stringResource(id = R.string.main_day1), true, {})
}