LobstersApp: replace with a BackgroundScaffold

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2021-02-17 00:10:28 +05:30
parent d82228483d
commit be58017cac
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80

View file

@ -1,114 +1,75 @@
package dev.msfjarvis.lobsters.ui.main package dev.msfjarvis.lobsters.ui.main
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.BottomNavigation import androidx.compose.material.BackdropScaffold
import androidx.compose.material.BottomNavigationItem import androidx.compose.material.BackdropScaffoldDefaults
import androidx.compose.material.Scaffold import androidx.compose.material.BackdropValue
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.rememberBackdropScaffoldState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.KEY_ROUTE
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.navigate
import androidx.navigation.compose.rememberNavController
import androidx.paging.compose.collectAsLazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems
import dev.msfjarvis.lobsters.ui.navigation.Destination import dev.msfjarvis.lobsters.R
import dev.msfjarvis.lobsters.ui.posts.HottestPosts import dev.msfjarvis.lobsters.ui.posts.HottestPosts
import dev.msfjarvis.lobsters.ui.posts.SavedPosts import dev.msfjarvis.lobsters.ui.posts.SavedPosts
import dev.msfjarvis.lobsters.ui.viewmodel.LobstersViewModel import dev.msfjarvis.lobsters.ui.viewmodel.LobstersViewModel
import dev.msfjarvis.lobsters.util.IconResource
import kotlinx.coroutines.launch
@Composable @Composable
fun LobstersApp() { fun LobstersApp() {
val viewModel: LobstersViewModel = viewModel() val viewModel: LobstersViewModel = viewModel()
val coroutineScope = rememberCoroutineScope() val scaffoldState = rememberBackdropScaffoldState(initialValue = BackdropValue.Concealed)
val navController = rememberNavController() BackdropScaffold(
scaffoldState = scaffoldState,
gesturesEnabled = false,
appBar = {
Spacer(modifier = Modifier.height(BackdropScaffoldDefaults.PeekHeight.times(0.3f)))
Text(
text = stringResource(id = R.string.app_name),
textAlign = TextAlign.Center,
fontSize = 18.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier.fillMaxWidth(),
)
Spacer(modifier = Modifier.height(BackdropScaffoldDefaults.PeekHeight.times(0.3f)))
},
backLayerContent = { BackgroundLayerContent(viewModel) },
) {
ForegroundLayerContent(viewModel)
}
}
@Composable
fun ForegroundLayerContent(
viewModel: LobstersViewModel,
) {
val hottestPosts = viewModel.posts.collectAsLazyPagingItems() val hottestPosts = viewModel.posts.collectAsLazyPagingItems()
val savedPosts by viewModel.savedPosts.collectAsState()
val hottestPostsListState = rememberLazyListState() val hottestPostsListState = rememberLazyListState()
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute =
navBackStackEntry?.arguments?.getString(KEY_ROUTE) ?: Destination.startDestination.route
val currentDestination = Destination.getDestinationFromRoute(currentRoute)
val navigateToDestination: (destination: Destination) -> Unit = { destination ->
navController.navigate(destination.route) {
launchSingleTop = true
popUpTo(navController.graph.startDestination) { inclusive = false }
}
}
val jumpToIndex: (Int) -> Unit = {
coroutineScope.launch {
hottestPostsListState.snapToItemIndex(it)
}
}
Scaffold(
bottomBar = {
LobstersBottomNav(
currentDestination,
navigateToDestination,
jumpToIndex,
)
},
) { innerPadding ->
NavHost(navController, startDestination = Destination.startDestination.route) {
composable(Destination.Hottest.route) {
HottestPosts( HottestPosts(
posts = hottestPosts, posts = hottestPosts,
listState = hottestPostsListState, listState = hottestPostsListState,
isPostSaved = viewModel::isPostSaved, isPostSaved = viewModel::isPostSaved,
saveAction = viewModel::toggleSave, saveAction = viewModel::toggleSave,
modifier = Modifier.padding(bottom = innerPadding.calculateBottomPadding()),
) )
} }
composable(Destination.Saved.route) {
@Composable
fun BackgroundLayerContent(
viewModel: LobstersViewModel,
) {
val savedPosts by viewModel.savedPosts.collectAsState()
SavedPosts( SavedPosts(
posts = savedPosts, posts = savedPosts,
saveAction = viewModel::toggleSave, saveAction = viewModel::toggleSave,
modifier = Modifier.padding(bottom = innerPadding.calculateBottomPadding()),
) )
}
}
}
}
@Composable
fun LobstersBottomNav(
currentDestination: Destination,
navigateToDestination: (destination: Destination) -> Unit,
jumpToIndex: (index: Int) -> Unit,
) {
BottomNavigation(modifier = Modifier.testTag("LobstersBottomNav")) {
Destination.values().forEach { screen ->
BottomNavigationItem(
icon = {
IconResource(
resourceId = screen.badgeRes,
contentDescription = stringResource(screen.labelRes),
)
},
label = { Text(stringResource(id = screen.labelRes)) },
selected = currentDestination == screen,
alwaysShowLabels = false,
onClick = {
if (screen != currentDestination) {
navigateToDestination(screen)
} else if (screen.route == Destination.Hottest.route) {
jumpToIndex(0)
}
}
)
}
}
} }