Skip to content
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
Expand Up @@ -14,8 +14,9 @@ import kotlinx.coroutines.launch

fun NavigationDispatcher.getBackStackStateHandle(
destinationId: Int?,
withBottomBar: Boolean? = null,
observer: (SavedStateHandle) -> Unit
) = emit {
) = emit(withBottomBar) {
val savedStateHandle = when (destinationId) {
null -> it.previousBackStackEntry!!.savedStateHandle
else -> it.getBackStackEntry(destinationId).savedStateHandle
Expand All @@ -25,8 +26,9 @@ fun NavigationDispatcher.getBackStackStateHandle(

fun NavigationDispatcher.getBackStackStateHandle(
destinationId: String?,
withBottomBar: Boolean? = null,
observer: (SavedStateHandle) -> Unit
) = emit {
) = emit(withBottomBar) {
val savedStateHandle = when (destinationId) {
null -> it.previousBackStackEntry!!.savedStateHandle
else -> it.getBackStackEntry(destinationId).savedStateHandle
Expand All @@ -45,8 +47,9 @@ fun <T> NavigationDispatcher.observeNavigationResult(
coroutineScope: CoroutineScope,
key: String,
initialValue: T,
withBottomBar: Boolean? = null,
observer: (T) -> Unit,
) = emit { navController ->
) = emit(withBottomBar) { navController ->
coroutineScope.launch {
navController.currentBackStackEntry!!.savedStateHandle.getStateFlow(key, initialValue)
.collect {
Expand All @@ -69,8 +72,10 @@ fun NavController.navigateWithObject(
val deepLinkMatch = graph.matchDeepLink(routeLink)
if (deepLinkMatch != null && arguments != null) {
val destination = deepLinkMatch.destination
val args = deepLinkMatch.matchingArgs ?: Bundle()
args.putAll(arguments)
val id = destination.id
navigate(id, arguments, navOptions, extras)
navigate(id, args, navOptions, extras)
} else {
navigate(route, navOptions, extras)
}
Expand All @@ -79,12 +84,16 @@ fun NavController.navigateWithObject(
// popUpToRoute - should always be the start destination of the bottomBar, not app
fun NavController.navigateToRootDestination(
route: String,
popInclusive: Boolean = false,
popUpToRoute: String = Destination.Tab1.route
) {
navigate(route) {
popUpTo(popUpToRoute) { saveState = true }
launchSingleTop = true
restoreState = true
popUpTo(popUpToRoute) {
saveState = true
inclusive = popInclusive
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModel
import com.skyyo.samples.application.Destination
import com.skyyo.samples.extensions.getBackStackStateHandle
import com.skyyo.samples.features.navigateWithResult.simple.dogFeed.DOG_STATUS_KEY
import com.skyyo.samples.features.navigationCores.bottomBar.WITH_BOTTOM_BAR_KEY
import com.skyyo.samples.utils.NavigationDispatcher
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
Expand All @@ -15,11 +16,12 @@ class DogContactsViewModel @Inject constructor(
handle: SavedStateHandle,
) : ViewModel() {

private val withBottomBar = handle.get<Boolean>(WITH_BOTTOM_BAR_KEY)
val dogId: String = requireNotNull(handle["dogId"])

@Suppress("MagicNumber")
fun popToDogFeed() {
navigationDispatcher.emit { navController ->
navigationDispatcher.emit(withBottomBar) { navController ->
val dogFeedScreenSavedStateHandle = navController.getBackStackStateHandle(Destination.DogFeed.route)
dogFeedScreenSavedStateHandle[DOG_STATUS_KEY] = "adopted ${System.nanoTime() / 1000f}"
navController.popBackStack(Destination.DogFeed.route, false)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.skyyo.samples.features.navigateWithResult.simple.dogDetails

import androidx.core.os.bundleOf
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import com.skyyo.samples.application.Destination
import com.skyyo.samples.extensions.navigateWithObject
import com.skyyo.samples.features.navigationCores.bottomBar.WITH_BOTTOM_BAR_KEY
import com.skyyo.samples.utils.NavigationDispatcher
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
Expand All @@ -13,9 +16,13 @@ class DogDetailsViewModel @Inject constructor(
handle: SavedStateHandle,
) : ViewModel() {

private val withBottomBar = handle.get<Boolean>(WITH_BOTTOM_BAR_KEY)
val dogId: String = requireNotNull(handle["dogId"])

fun goContacts() = navigationDispatcher.emit {
it.navigate(Destination.DogContacts.createRoute("3333"))
fun goContacts() = navigationDispatcher.emit(withBottomBar) {
it.navigateWithObject(
route = Destination.DogContacts.createRoute("3333"),
arguments = bundleOf(WITH_BOTTOM_BAR_KEY to withBottomBar)
)
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.skyyo.samples.features.navigateWithResult.simple.dogFeed

import androidx.core.os.bundleOf
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.skyyo.samples.application.Destination
import com.skyyo.samples.extensions.navigateWithObject
import com.skyyo.samples.extensions.observeNavigationResult
import com.skyyo.samples.features.navigationCores.bottomBar.WITH_BOTTOM_BAR_KEY
import com.skyyo.samples.utils.NavigationDispatcher
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
Expand All @@ -17,19 +20,26 @@ class DogFeedViewModel @Inject constructor(
private val handle: SavedStateHandle,
) : ViewModel() {

private val withBottomBar = handle.get<Boolean>(WITH_BOTTOM_BAR_KEY)
val dogStatus = handle.getStateFlow(DOG_STATUS_KEY, "")

init {
observeDogStatusResult()
}

private fun observeDogStatusResult() {
navigationDispatcher.observeNavigationResult(viewModelScope, DOG_STATUS_KEY, "") {
handle[DOG_STATUS_KEY] = it
}
navigationDispatcher.observeNavigationResult(
coroutineScope = viewModelScope,
key = DOG_STATUS_KEY,
initialValue = "",
withBottomBar = withBottomBar
) { handle[DOG_STATUS_KEY] = it }
}

fun goDogDetails() = navigationDispatcher.emit {
it.navigate(Destination.DogDetails.createRoute("2211"))
fun goDogDetails() = navigationDispatcher.emit(withBottomBar) {
it.navigateWithObject(
route = Destination.DogDetails.createRoute("2211"),
arguments = bundleOf(WITH_BOTTOM_BAR_KEY to withBottomBar)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.skyyo.samples.application.Destination
import com.skyyo.samples.application.models.Dog
import com.skyyo.samples.extensions.getBackStackStateHandle
import com.skyyo.samples.features.navigateWithResult.withObject.catFeed.CAT_KEY
import com.skyyo.samples.features.navigationCores.bottomBar.WITH_BOTTOM_BAR_KEY
import com.skyyo.samples.utils.NavigationDispatcher
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
Expand All @@ -16,16 +17,17 @@ class CatContactsViewModel @Inject constructor(
handle: SavedStateHandle,
) : ViewModel() {

private val withBottomBar = handle.get<Boolean>(WITH_BOTTOM_BAR_KEY)
val cat: Dog = requireNotNull(handle["cat"])
private lateinit var catFeedHandle: SavedStateHandle

init {
navigationDispatcher.getBackStackStateHandle(Destination.CatFeed.route) {
navigationDispatcher.getBackStackStateHandle(Destination.CatFeed.route, withBottomBar) {
catFeedHandle = it
}
}

fun popToCatFeed() = navigationDispatcher.emit {
fun popToCatFeed() = navigationDispatcher.emit(withBottomBar) {
catFeedHandle[CAT_KEY] = cat
it.popBackStack(Destination.CatFeed.route, false)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.lifecycle.ViewModel
import com.skyyo.samples.application.Destination
import com.skyyo.samples.application.models.Dog
import com.skyyo.samples.extensions.navigateWithObject
import com.skyyo.samples.features.navigationCores.bottomBar.WITH_BOTTOM_BAR_KEY
import com.skyyo.samples.utils.NavigationDispatcher
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
Expand All @@ -16,12 +17,13 @@ class CatDetailsViewModel @Inject constructor(
private val handle: SavedStateHandle,
) : ViewModel() {

private val withBottomBar = handle.get<Boolean>(WITH_BOTTOM_BAR_KEY)
val cat: Dog = requireNotNull(handle["cat"])

fun goCatContacts() = navigationDispatcher.emit {
fun goCatContacts() = navigationDispatcher.emit(withBottomBar) {
it.navigateWithObject(
route = Destination.CatContacts.route,
arguments = bundleOf("cat" to cat)
arguments = bundleOf("cat" to cat, WITH_BOTTOM_BAR_KEY to withBottomBar)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.skyyo.samples.application.Destination
import com.skyyo.samples.application.models.Dog
import com.skyyo.samples.extensions.navigateWithObject
import com.skyyo.samples.extensions.observeNavigationResult
import com.skyyo.samples.features.navigationCores.bottomBar.WITH_BOTTOM_BAR_KEY
import com.skyyo.samples.utils.NavigationDispatcher
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
Expand All @@ -20,6 +21,7 @@ class CatFeedViewModel @Inject constructor(
private val handle: SavedStateHandle,
) : ViewModel() {

private val withBottomBar = handle.get<Boolean>(WITH_BOTTOM_BAR_KEY)
// this is the result from CatContacts screen
val cat = handle.getStateFlow<Dog?>(CAT_KEY, null)

Expand All @@ -28,15 +30,21 @@ class CatFeedViewModel @Inject constructor(
}

private fun observeCatResult() {
navigationDispatcher.observeNavigationResult<Dog?>(viewModelScope, CAT_KEY, null) {
handle[CAT_KEY] = it
}
navigationDispatcher.observeNavigationResult<Dog?>(
coroutineScope = viewModelScope,
key = CAT_KEY,
initialValue = null,
withBottomBar = withBottomBar
) { handle[CAT_KEY] = it }
}

fun goCatDetails() = navigationDispatcher.emit {
fun goCatDetails() = navigationDispatcher.emit(withBottomBar) {
it.navigateWithObject(
route = Destination.CatDetails.route,
arguments = bundleOf(CAT_KEY to Dog(id = 99, name = "Kit"))
arguments = bundleOf(
CAT_KEY to Dog(id = 99, name = "Kit"),
WITH_BOTTOM_BAR_KEY to withBottomBar
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ private const val EXPAND_ANIMATION_DURATION = 300
private const val COLLAPSE_ANIMATION_DURATION = 300
private const val FADE_IN_ANIMATION_DURATION = 350
private const val FADE_OUT_ANIMATION_DURATION = 300
val BOTTOM_BAR_HEIGHT = 56.dp

@Composable
fun AnimatedBottomBar(
Expand Down Expand Up @@ -54,13 +55,13 @@ fun AnimatedBottomBar(
val enterSlide = remember {
slideIn(
animationSpec = tween(EXPAND_ANIMATION_DURATION),
initialOffset = { with(density) { IntOffset(0, 56.dp.roundToPx()) } }
initialOffset = { with(density) { IntOffset(0, BOTTOM_BAR_HEIGHT.roundToPx()) } }
)
}
val exitSlide = remember {
slideOut(
animationSpec = tween(COLLAPSE_ANIMATION_DURATION),
targetOffset = { with(density) { IntOffset(0, 56.dp.roundToPx()) } }
targetOffset = { with(density) { IntOffset(0, BOTTOM_BAR_HEIGHT.roundToPx()) } }
)
}

Expand All @@ -73,7 +74,7 @@ fun AnimatedBottomBar(
BottomNavigation(
backgroundColor = DarkGray,
modifier = Modifier.windowInsetsBottomHeight(
WindowInsets.navigationBars.add(WindowInsets(bottom = 56.dp))
WindowInsets.navigationBars.add(WindowInsets(bottom = BOTTOM_BAR_HEIGHT))
)
) {
items.forEachIndexed { index, screen ->
Expand Down
Loading