Skip to content

Commit

Permalink
Merge pull request DroidKaigi#974 from ked4ma/feature/handle-consecut…
Browse files Browse the repository at this point in the history
…ive-navigation

prevent consecutive navigation event
  • Loading branch information
takahirom committed Aug 27, 2023
2 parents e1aa6af + 5ac8ad0 commit 62163be
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 17 deletions.
1 change: 1 addition & 0 deletions app-android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ dependencies {
implementation(projects.core.model)
implementation(projects.core.data)
implementation(projects.core.designsystem)
implementation(projects.core.ui)
implementation(libs.composeNavigation)
implementation(libs.composeHiltNavigtation)
implementation(libs.composeMaterialWindowSize)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.core.content.ContextCompat.startActivity
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.core.net.toUri
import androidx.core.os.bundleOf
import androidx.hilt.navigation.compose.hiltViewModel
Expand Down Expand Up @@ -73,6 +73,7 @@ import io.github.droidkaigi.confsched2023.staff.staffScreen
import io.github.droidkaigi.confsched2023.stamps.navigateStampsScreen
import io.github.droidkaigi.confsched2023.stamps.nestedStampsScreen
import io.github.droidkaigi.confsched2023.stamps.stampsScreenRoute
import io.github.droidkaigi.confsched2023.ui.handleOnClickIfNotNavigating
import kotlinx.collections.immutable.PersistentList

@Composable
Expand Down Expand Up @@ -171,9 +172,15 @@ private fun NavGraphBuilder.mainScreen(
)
// For KMP, we are not using navigation abstraction for contributors screen
composable(contributorsScreenRoute) {
val lifecycleOwner = LocalLifecycleOwner.current
ContributorsScreen(
viewModel = hiltViewModel<ContributorsViewModel>(),
onNavigationIconClick = navController::popBackStack,
onNavigationIconClick = {
handleOnClickIfNotNavigating(
lifecycleOwner,
mainNestedNavController::popBackStack,
)
},
onContributorItemClick = externalNavController::navigate,
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.github.droidkaigi.confsched2023.ui

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner

/**
* Invoke "onClick" if current lifecycle isn't operating other navigation.
* @param owner a current LifecycleOwner
* @param onClick the method that want to invoke
*/
fun handleOnClickIfNotNavigating(owner: LifecycleOwner, onClick: () -> Unit) {
// https://stackoverflow.com/a/76386604/4339442
val currentState = owner.lifecycle.currentState
if (currentState.isAtLeast(Lifecycle.State.RESUMED)) {
onClick()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ import androidx.compose.ui.text.lerp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.lerp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.Lifecycle
import io.github.droidkaigi.confsched2023.designsystem.preview.MultiLanguagePreviews
import io.github.droidkaigi.confsched2023.designsystem.preview.MultiThemePreviews
import io.github.droidkaigi.confsched2023.designsystem.theme.KaigiTheme
import io.github.droidkaigi.confsched2023.sessions.SessionsStrings
import io.github.droidkaigi.confsched2023.ui.handleOnClickIfNotNavigating
import kotlin.math.min

@OptIn(ExperimentalLayoutApi::class)
Expand Down Expand Up @@ -125,14 +125,7 @@ fun BookmarkTopArea(
contentDescription = null,
modifier = Modifier
.size(24.dp)
.clickable {
// Ignore click events when you've started navigating to another screen
// https://stackoverflow.com/a/76386604/4339442
val currentState = lifecycleOwner.lifecycle.currentState
if (currentState.isAtLeast(Lifecycle.State.RESUMED)) {
onBackPressClick()
}
},
.clickable { handleOnClickIfNotNavigating(lifecycleOwner, onBackPressClick) },
)
Text(
text = SessionsStrings.Bookmark.asString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.TextStyle
Expand All @@ -37,6 +38,7 @@ import io.github.droidkaigi.confsched2023.designsystem.preview.MultiLanguagePrev
import io.github.droidkaigi.confsched2023.designsystem.preview.MultiThemePreviews
import io.github.droidkaigi.confsched2023.designsystem.theme.KaigiTheme
import io.github.droidkaigi.confsched2023.sessions.SessionsStrings.SearchPlaceHolder
import io.github.droidkaigi.confsched2023.ui.handleOnClickIfNotNavigating
import io.github.droidkaigi.confsched2023.ui.isTest

@OptIn(ExperimentalMaterial3Api::class)
Expand All @@ -48,13 +50,14 @@ fun SearchTextFieldAppBar(
testTag: String,
modifier: Modifier = Modifier,
) {
val lifecycleOwner = LocalLifecycleOwner.current
TopAppBar(
modifier = modifier,
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant,
),
navigationIcon = {
IconButton(onClick = onBackClick) {
IconButton(onClick = { handleOnClickIfNotNavigating(lifecycleOwner, onBackClick) }) {
Icon(
imageVector = Icons.Default.ArrowBack,
contentDescription = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import io.github.droidkaigi.confsched2023.designsystem.preview.MultiLanguagePreviews
import io.github.droidkaigi.confsched2023.designsystem.preview.MultiThemePreviews
import io.github.droidkaigi.confsched2023.model.MultiLangText
import io.github.droidkaigi.confsched2023.ui.handleOnClickIfNotNavigating
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf

Expand All @@ -40,6 +42,7 @@ fun TimetableItemDetailScreenTopAppBar(
scrollBehavior.state.collapsedFraction >= 0.5f
}
}
val lifecycleOwner = LocalLifecycleOwner.current
LargeTopAppBar(
title = {
// TODO: Need some better way to switch these text styles
Expand All @@ -65,7 +68,9 @@ fun TimetableItemDetailScreenTopAppBar(
}
},
navigationIcon = {
IconButton(onClick = onNavigationIconClick) {
IconButton(onClick = {
handleOnClickIfNotNavigating(lifecycleOwner, onNavigationIconClick)
}) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.platform.testTag
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
Expand All @@ -28,6 +29,7 @@ import io.github.droidkaigi.confsched2023.model.Sponsor
import io.github.droidkaigi.confsched2023.sponsors.section.SponsorList
import io.github.droidkaigi.confsched2023.sponsors.section.SponsorListUiState
import io.github.droidkaigi.confsched2023.ui.SnackbarMessageEffect
import io.github.droidkaigi.confsched2023.ui.handleOnClickIfNotNavigating

const val sponsorsScreenRoute = "sponsors"
fun NavGraphBuilder.sponsorsScreen(
Expand Down Expand Up @@ -82,6 +84,7 @@ private fun SponsorsScreen(
onSponsorClick: (Sponsor) -> Unit,
) {
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
val lifecycleOwner = LocalLifecycleOwner.current
Scaffold(
modifier = Modifier
.nestedScroll(scrollBehavior.nestedScrollConnection)
Expand All @@ -92,9 +95,9 @@ private fun SponsorsScreen(
Text(text = SponsorsStrings.Sponsor.asString())
},
navigationIcon = {
IconButton(
onClick = onBackClick,
) {
IconButton(onClick = {
handleOnClickIfNotNavigating(lifecycleOwner, onBackClick)
}) {
Icon(
imageVector = Icons.Default.ArrowBack,
contentDescription = "Back",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import io.github.droidkaigi.confsched2023.staff.section.StaffSheet
import io.github.droidkaigi.confsched2023.staff.section.StaffSheetUiState
import io.github.droidkaigi.confsched2023.ui.SnackbarMessageEffect
import io.github.droidkaigi.confsched2023.ui.handleOnClickIfNotNavigating

const val staffScreenRoute = "staff"

Expand Down Expand Up @@ -76,12 +78,15 @@ private fun StaffScreen(
onBackClick: () -> Unit,
) {
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
val lifecycleOwner = LocalLifecycleOwner.current
Scaffold(
topBar = {
LargeTopAppBar(
title = { Text(text = "Staff") },
navigationIcon = {
IconButton(onClick = onBackClick) {
IconButton(onClick = {
handleOnClickIfNotNavigating(lifecycleOwner, onBackClick)
}) {
Icon(
imageVector = Icons.Default.ArrowBack,
contentDescription = "Back",
Expand Down

0 comments on commit 62163be

Please sign in to comment.