refactor home screen ui options to viewmodel

This commit is contained in:
Owen LeJeune
2023-06-14 18:36:53 -04:00
parent 7941200b13
commit 3c2839f608
6 changed files with 56 additions and 76 deletions

View File

@@ -61,6 +61,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.*
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.text.HtmlCompat
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import coil.compose.AsyncImage
import coil.compose.rememberAsyncImagePainter
@@ -71,6 +72,7 @@ import com.owenlejeune.tvtime.extensions.toDp
import com.owenlejeune.tvtime.extensions.unlessEmpty
import com.owenlejeune.tvtime.preferences.AppPreferences
import com.owenlejeune.tvtime.ui.navigation.AppNavItem
import com.owenlejeune.tvtime.ui.viewmodel.HomeScreenViewModel
import com.owenlejeune.tvtime.utils.types.MediaViewType
import com.owenlejeune.tvtime.utils.SessionManager
import com.owenlejeune.tvtime.utils.TmdbUtils
@@ -209,7 +211,6 @@ fun SearchView(
title: String,
appNavController: NavHostController,
mediaType: MediaViewType,
fab: MutableState<@Composable () -> Unit>,
preferences: AppPreferences = KoinJavaComponent.get(AppPreferences::class.java)
) {
val route = AppNavItem.SearchView.withArgs(mediaType, title)
@@ -220,7 +221,8 @@ fun SearchView(
appNavController.navigate(route)
}
} else {
fab.value = @Composable {
val homeScreenViewModel = viewModel<HomeScreenViewModel>()
homeScreenViewModel.fab.value = @Composable {
FloatingActionButton(
onClick = {
appNavController.navigate(route)

View File

@@ -1,15 +1,13 @@
package com.owenlejeune.tvtime.ui.navigation
import androidx.compose.foundation.layout.RowScope
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Face
import androidx.compose.material.icons.outlined.Movie
import androidx.compose.material.icons.outlined.Person
import androidx.compose.material.icons.outlined.Tv
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
@@ -17,9 +15,10 @@ import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.preferences.AppPreferences
import com.owenlejeune.tvtime.ui.screens.AccountViewContent
import com.owenlejeune.tvtime.ui.screens.tabs.MediaTab
import com.owenlejeune.tvtime.utils.types.MediaViewType
import com.owenlejeune.tvtime.ui.screens.tabs.PeopleTab
import com.owenlejeune.tvtime.ui.viewmodel.HomeScreenViewModel
import com.owenlejeune.tvtime.utils.ResourceUtils
import com.owenlejeune.tvtime.utils.types.MediaViewType
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -27,40 +26,33 @@ import org.koin.core.component.inject
fun HomeScreenNavHost(
appNavController: NavHostController,
navController: NavHostController,
fab: MutableState<@Composable () -> Unit>,
appBarTitle: MutableState<@Composable () -> Unit>,
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
startDestination: String = HomeScreenNavItem.SortedItems[0].route
) {
val homeScreenViewModel = viewModel<HomeScreenViewModel>()
NavHost(navController = navController, startDestination = startDestination) {
composable(HomeScreenNavItem.Movies.route) {
appBarActions.value = {}
homeScreenViewModel.appBarActions.value = {}
MediaTab(
appBarTitle = appBarTitle,
appNavController = appNavController,
mediaType = MediaViewType.MOVIE,
fab = fab
)
}
composable(HomeScreenNavItem.TV.route) {
appBarActions.value = {}
homeScreenViewModel.appBarActions.value = {}
MediaTab(
appBarTitle = appBarTitle,
appNavController = appNavController,
mediaType = MediaViewType.TV,
fab = fab
)
}
composable(route = HomeScreenNavItem.Account.route) {
AccountViewContent(appNavController = appNavController)
fab.value = {}
homeScreenViewModel.fab.value = {}
}
composable(HomeScreenNavItem.People.route) {
appBarActions.value = {}
homeScreenViewModel.appBarActions.value = {}
PeopleTab(
appBarTitle = appBarTitle,
appNavController = appNavController,
fab = fab
)
}
}

View File

@@ -39,6 +39,7 @@ import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
@@ -51,6 +52,7 @@ import com.owenlejeune.tvtime.ui.components.ProfileMenuContainer
import com.owenlejeune.tvtime.ui.components.ProfileMenuDefaults
import com.owenlejeune.tvtime.ui.navigation.HomeScreenNavItem
import com.owenlejeune.tvtime.ui.navigation.HomeScreenNavHost
import com.owenlejeune.tvtime.ui.viewmodel.HomeScreenViewModel
import org.koin.java.KoinJavaComponent
@OptIn(ExperimentalMaterial3Api::class)
@@ -68,9 +70,7 @@ fun HomeScreen(
TopAppBarDefaults.exitUntilCollapsedScrollBehavior(decayAnimationSpec, topAppBarScrollState)
}
val appBarTitle = remember { mutableStateOf<@Composable () -> Unit>({}) }
val appBarActions = remember { mutableStateOf<@Composable RowScope.() -> Unit>({}) }
val fab = remember { mutableStateOf<@Composable () -> Unit>({}) }
val homeScreenViewModel = viewModel<HomeScreenViewModel>()
val showProfileMenuOverlay = remember { mutableStateOf(false) }
val navigationIcon = @Composable {
@@ -94,14 +94,13 @@ fun HomeScreen(
topBar = {
if (windowSize != WindowSizeClass.Expanded) {
TopBar(
title = appBarTitle.value,
scrollBehavior = scrollBehavior,
appBarActions = appBarActions,
navigationIcon = navigationIcon
)
}
},
floatingActionButton = {
val fab = remember { homeScreenViewModel.fab }
fab.value()
},
bottomBar = {
@@ -115,9 +114,6 @@ fun HomeScreen(
windowSize = windowSize,
appNavController = appNavController,
navController = navController,
fab = fab,
appBarTitle = appBarTitle,
appBarActions = appBarActions,
topBarScrollBehaviour = scrollBehavior,
mainNavStartRoute = mainNavStartRoute,
navigationIcon = navigationIcon
@@ -129,21 +125,21 @@ fun HomeScreen(
@Composable
private fun TopBar(
title: @Composable () -> Unit,
scrollBehavior: TopAppBarScrollBehavior,
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
navigationIcon: @Composable () -> Unit = {}
) {
val homeScreenViewModel = viewModel<HomeScreenViewModel>()
val title = remember { homeScreenViewModel.appBarTitle }
val actions = remember { homeScreenViewModel.appBarActions }
LargeTopAppBar(
title = title,
title = { Text(text = title.value) },
scrollBehavior = scrollBehavior,
colors = TopAppBarDefaults
.largeTopAppBarColors(
scrolledContainerColor = MaterialTheme.colorScheme.background
),
actions = {
appBarActions.value(this)
},
actions = actions.value,
navigationIcon = navigationIcon
)
}
@@ -188,10 +184,7 @@ private fun MainContent(
windowSize: WindowSizeClass,
appNavController: NavHostController,
navController: NavHostController,
fab: MutableState<@Composable () -> Unit>,
topBarScrollBehaviour: TopAppBarScrollBehavior,
appBarTitle: MutableState<@Composable () -> Unit>,
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
navigationIcon: @Composable () -> Unit = {},
mainNavStartRoute: String = HomeScreenNavItem.SortedItems[0].route
) {
@@ -199,9 +192,6 @@ private fun MainContent(
DualColumnMainContent(
appNavController = appNavController,
navController = navController,
fab = fab,
appBarTitle = appBarTitle,
appBarActions = appBarActions,
topBarScrollBehaviour = topBarScrollBehaviour,
mainNavStartRoute = mainNavStartRoute,
navigationIcon = navigationIcon
@@ -210,9 +200,6 @@ private fun MainContent(
SingleColumnMainContent(
appNavController = appNavController,
navController = navController,
fab = fab,
appBarTitle = appBarTitle,
appBarActions = appBarActions,
mainNavStartRoute = mainNavStartRoute
)
}
@@ -222,17 +209,11 @@ private fun MainContent(
private fun SingleColumnMainContent(
appNavController: NavHostController,
navController: NavHostController,
fab: MutableState<@Composable () -> Unit>,
appBarTitle: MutableState<@Composable () -> Unit>,
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
mainNavStartRoute: String = HomeScreenNavItem.SortedItems[0].route
) {
MainMediaView(
appNavController = appNavController,
navController = navController,
fab = fab,
appBarTitle = appBarTitle,
appBarActions = appBarActions,
mainNavStartRoute = mainNavStartRoute
)
}
@@ -241,10 +222,7 @@ private fun SingleColumnMainContent(
private fun DualColumnMainContent(
appNavController: NavHostController,
navController: NavHostController,
fab: MutableState<@Composable () -> Unit>,
topBarScrollBehaviour: TopAppBarScrollBehavior,
appBarTitle: MutableState<@Composable () -> Unit>,
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
navigationIcon: @Composable () -> Unit = {},
mainNavStartRoute: String = HomeScreenNavItem.SortedItems[0].route,
preferences: AppPreferences = KoinJavaComponent.get(AppPreferences::class.java)
@@ -276,17 +254,12 @@ private fun DualColumnMainContent(
}
Column {
TopBar(
title = appBarTitle.value,
scrollBehavior = topBarScrollBehaviour,
appBarActions = appBarActions,
navigationIcon = navigationIcon
)
MainMediaView(
appNavController = appNavController,
navController = navController,
fab = fab,
appBarTitle = appBarTitle,
appBarActions = appBarActions,
mainNavStartRoute = mainNavStartRoute
)
}
@@ -297,9 +270,6 @@ private fun DualColumnMainContent(
private fun MainMediaView(
appNavController: NavHostController,
navController: NavHostController,
fab: MutableState<@Composable () -> Unit>,
appBarTitle: MutableState<@Composable () -> Unit>,
appBarActions: MutableState<RowScope.() -> Unit> = mutableStateOf({}),
mainNavStartRoute: String = HomeScreenNavItem.SortedItems[0].route
) {
val activity = LocalContext.current as Activity
@@ -311,9 +281,6 @@ private fun MainMediaView(
HomeScreenNavHost(
appNavController = appNavController,
navController = navController,
fab = fab,
appBarTitle = appBarTitle,
appBarActions = appBarActions,
startDestination = mainNavStartRoute
)
}

View File

@@ -5,6 +5,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import androidx.paging.compose.collectAsLazyPagingItems
@@ -18,30 +19,29 @@ import com.owenlejeune.tvtime.ui.components.SearchView
import com.owenlejeune.tvtime.ui.navigation.AppNavItem
import com.owenlejeune.tvtime.ui.navigation.MediaTabNavItem
import com.owenlejeune.tvtime.ui.components.Tabs
import com.owenlejeune.tvtime.ui.viewmodel.HomeScreenViewModel
import com.owenlejeune.tvtime.ui.viewmodel.MediaTabViewModel
import com.owenlejeune.tvtime.utils.types.MediaViewType
@OptIn(ExperimentalPagerApi::class)
@Composable
fun MediaTab(
appBarTitle: MutableState<@Composable () -> Unit>,
appNavController: NavHostController,
mediaType: MediaViewType,
fab: MutableState<@Composable () -> Unit>
mediaType: MediaViewType
) {
val titleText = when (mediaType) {
val homeScreenViewModel = viewModel<HomeScreenViewModel>()
val titleText = when (mediaType) {
MediaViewType.MOVIE -> stringResource(id = R.string.nav_movies_title)
MediaViewType.TV -> stringResource(id = R.string.nav_tv_title)
else -> ""
}
appBarTitle.value = @Composable { Text(text = titleText) }
homeScreenViewModel.appBarTitle.value = titleText
Column {
SearchView(
title = titleText,
appNavController = appNavController,
mediaType = mediaType,
fab = fab
mediaType = mediaType
)
val tabs = when (mediaType) {

View File

@@ -5,30 +5,29 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.paging.compose.collectAsLazyPagingItems
import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.ui.components.PagingPeoplePosterGrid
import com.owenlejeune.tvtime.ui.components.SearchView
import com.owenlejeune.tvtime.ui.navigation.AppNavItem
import com.owenlejeune.tvtime.ui.viewmodel.HomeScreenViewModel
import com.owenlejeune.tvtime.ui.viewmodel.PeopleTabViewModel
import com.owenlejeune.tvtime.utils.types.MediaViewType
@Composable
fun PeopleTab(
appBarTitle: MutableState<@Composable () -> Unit>,
appNavController: NavHostController,
fab: MutableState<@Composable () -> Unit>
) {
val titleText = stringResource(id = R.string.popular_today_header)
appBarTitle.value = { Text(text = titleText) }
val homeScreenViewModel = viewModel<HomeScreenViewModel>()
homeScreenViewModel.appBarTitle.value = stringResource(id = R.string.popular_today_header)
Column {
SearchView(
title = titleText,
title = stringResource(id = R.string.popular_today_header),
appNavController = appNavController,
mediaType = MediaViewType.PERSON,
fab = fab
mediaType = MediaViewType.PERSON
)
val peopleList = PeopleTabViewModel().popularPeople.collectAsLazyPagingItems()

View File

@@ -0,0 +1,20 @@
package com.owenlejeune.tvtime.ui.viewmodel
import androidx.compose.foundation.layout.RowScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
class HomeScreenViewModel: ViewModel() {
private object Backer {
val appBarTitle = mutableStateOf("")
val appBarActions = mutableStateOf<@Composable RowScope.() -> Unit>( {} )
val fab = mutableStateOf<@Composable () -> Unit>( {} )
}
val appBarTitle = Backer.appBarTitle
val appBarActions = Backer.appBarActions
val fab = Backer.fab
}