main: split out LobstersApp

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2021-02-16 23:54:16 +05:30
parent 8f249ec2a2
commit d82228483d
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
2 changed files with 114 additions and 112 deletions

View file

@ -0,0 +1,114 @@
package dev.msfjarvis.lobsters.ui.main
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
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 dev.msfjarvis.lobsters.ui.navigation.Destination
import dev.msfjarvis.lobsters.ui.posts.HottestPosts
import dev.msfjarvis.lobsters.ui.posts.SavedPosts
import dev.msfjarvis.lobsters.ui.viewmodel.LobstersViewModel
import dev.msfjarvis.lobsters.util.IconResource
import kotlinx.coroutines.launch
@Composable
fun LobstersApp() {
val viewModel: LobstersViewModel = viewModel()
val coroutineScope = rememberCoroutineScope()
val navController = rememberNavController()
val hottestPosts = viewModel.posts.collectAsLazyPagingItems()
val savedPosts by viewModel.savedPosts.collectAsState()
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(
posts = hottestPosts,
listState = hottestPostsListState,
isPostSaved = viewModel::isPostSaved,
saveAction = viewModel::toggleSave,
modifier = Modifier.padding(bottom = innerPadding.calculateBottomPadding()),
)
}
composable(Destination.Saved.route) {
SavedPosts(
posts = savedPosts,
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)
}
}
)
}
}
}

View file

@ -3,39 +3,12 @@ package dev.msfjarvis.lobsters.ui.main
import android.os.Bundle import android.os.Bundle
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Providers import androidx.compose.runtime.Providers
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
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 dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import dev.msfjarvis.lobsters.ui.navigation.Destination
import dev.msfjarvis.lobsters.ui.posts.HottestPosts
import dev.msfjarvis.lobsters.ui.posts.SavedPosts
import dev.msfjarvis.lobsters.ui.theme.LobstersTheme import dev.msfjarvis.lobsters.ui.theme.LobstersTheme
import dev.msfjarvis.lobsters.ui.urllauncher.LocalUrlLauncher import dev.msfjarvis.lobsters.ui.urllauncher.LocalUrlLauncher
import dev.msfjarvis.lobsters.ui.urllauncher.UrlLauncher import dev.msfjarvis.lobsters.ui.urllauncher.UrlLauncher
import dev.msfjarvis.lobsters.ui.viewmodel.LobstersViewModel
import dev.msfjarvis.lobsters.util.IconResource
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.launch
@AndroidEntryPoint @AndroidEntryPoint
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
@ -52,88 +25,3 @@ class MainActivity : AppCompatActivity() {
} }
} }
} }
@Composable
fun LobstersApp() {
val viewModel: LobstersViewModel = viewModel()
val coroutineScope = rememberCoroutineScope()
val navController = rememberNavController()
val hottestPosts = viewModel.posts.collectAsLazyPagingItems()
val savedPosts by viewModel.savedPosts.collectAsState()
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(
posts = hottestPosts,
listState = hottestPostsListState,
isPostSaved = viewModel::isPostSaved,
saveAction = viewModel::toggleSave,
modifier = Modifier.padding(bottom = innerPadding.calculateBottomPadding()),
)
}
composable(Destination.Saved.route) {
SavedPosts(
posts = savedPosts,
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)
}
}
)
}
}
}