diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/components/Widgets.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/components/Widgets.kt index 2c03c84..7fd9bea 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/components/Widgets.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/components/Widgets.kt @@ -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.fab.value = @Composable { FloatingActionButton( onClick = { appNavController.navigate(route) diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/HomeScreenNavigation.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/HomeScreenNavigation.kt index 820be9a..63c5d6a 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/HomeScreenNavigation.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/HomeScreenNavigation.kt @@ -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() + 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 ) } } diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/HomeScreen.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/HomeScreen.kt index b08c60d..891f10d 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/HomeScreen.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/HomeScreen.kt @@ -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() 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() + 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 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 ) } diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/MediaTab.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/MediaTab.kt index 66a5925..adb8a4b 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/MediaTab.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/MediaTab.kt @@ -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() + 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) { diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/PeopleTab.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/PeopleTab.kt index d6650ec..7ba61b9 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/PeopleTab.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/PeopleTab.kt @@ -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.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() diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/viewmodel/HomeScreenViewModel.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/viewmodel/HomeScreenViewModel.kt new file mode 100644 index 0000000..583b03f --- /dev/null +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/viewmodel/HomeScreenViewModel.kt @@ -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 + +} \ No newline at end of file