HomeScreen.kt
package com.louisfn.somovie.feature.home.container
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.louisfn.somovie.core.logger.Logger
import com.louisfn.somovie.domain.model.ExploreCategory
import com.louisfn.somovie.domain.model.Movie
import com.louisfn.somovie.feature.home.account.accountGraph
import com.louisfn.somovie.feature.home.common.HomeItemState
import com.louisfn.somovie.feature.home.common.rememberHomeItemState
import com.louisfn.somovie.feature.home.discover.discoverGraph
import com.louisfn.somovie.feature.home.explore.exploreGraph
import com.louisfn.somovie.feature.home.watchlist.watchListGraph
@Composable
internal fun HomeScreen(
showDetails: (Movie) -> Unit,
showMore: (ExploreCategory) -> Unit,
) {
Logger.v("Navigation - HomeScreen")
val navController = rememberNavController()
val homeItemState = rememberHomeItemState()
Scaffold(
modifier = Modifier.systemBarsPadding(),
bottomBar = {
BottomBar(
navController = navController,
homeItemState = homeItemState,
)
},
) {
NavHost(
modifier = Modifier.fillMaxSize().padding(it),
navController = navController,
startDestination = HomeBottomSheetItem.Explore.destination.route,
) {
exploreGraph(
homeItemState = homeItemState,
showDetail = showDetails,
showMore = showMore,
)
watchListGraph(
showDetails = showDetails,
)
discoverGraph(
showAccount = { navController.navigate(HomeBottomSheetItem.Account) },
)
accountGraph()
}
}
}
@Composable
private fun BottomBar(
navController: NavController,
homeItemState: HomeItemState,
) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
BottomBar(
currentDestination = currentDestination,
onItemClick = { item ->
if (item.destination.route != currentDestination?.route) {
navController.navigate(item)
} else {
homeItemState.homeItemReselect()
}
},
)
}
@Composable
private fun BottomBar(
currentDestination: NavDestination?,
onItemClick: (HomeBottomSheetItem) -> Unit,
) {
BottomNavigation(elevation = 0.dp) {
HomeBottomSheetItems.forEach { item ->
BottomNavigationItem(
item = item,
currentDestination = currentDestination,
onItemClick = onItemClick,
)
}
}
}
@Composable
private fun RowScope.BottomNavigationItem(
item: HomeBottomSheetItem,
currentDestination: NavDestination?,
onItemClick: (HomeBottomSheetItem) -> Unit,
) {
val isCurrentDestination = currentDestination?.route == item.destination.route
BottomNavigationItem(
label = { Text(stringResource(id = item.titleId)) },
icon = { Icon(item.icon, contentDescription = null) },
selected = isCurrentDestination,
onClick = { onItemClick(item) },
selectedContentColor = MaterialTheme.colors.secondary,
unselectedContentColor = MaterialTheme.colors.onPrimary,
)
}
private fun NavController.navigate(item: HomeBottomSheetItem) {
navigate(item.destination.route) {
popUpTo(graph.findStartDestination().id)
launchSingleTop = true
}
}