mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-17 17:21:06 -05:00
launch new view when tapping movie poster
This commit is contained in:
@@ -2,5 +2,6 @@ package com.owenlejeune.tvtime.api.tmdb.model
|
|||||||
|
|
||||||
abstract class MediaItem(
|
abstract class MediaItem(
|
||||||
open val posterPath: String?,
|
open val posterPath: String?,
|
||||||
@Transient open val title: String
|
@Transient open val title: String,
|
||||||
|
@Transient open val id: Int
|
||||||
)
|
)
|
||||||
@@ -4,5 +4,6 @@ import com.google.gson.annotations.SerializedName
|
|||||||
|
|
||||||
data class PopularMovie(
|
data class PopularMovie(
|
||||||
@SerializedName("poster_path") override val posterPath: String?,
|
@SerializedName("poster_path") override val posterPath: String?,
|
||||||
@SerializedName("title") override val title: String
|
@SerializedName("title") override val title: String,
|
||||||
): MediaItem(posterPath, title)
|
@SerializedName("id") override val id: Int
|
||||||
|
): MediaItem(posterPath, title, id)
|
||||||
@@ -4,5 +4,6 @@ import com.google.gson.annotations.SerializedName
|
|||||||
|
|
||||||
data class PopularTv(
|
data class PopularTv(
|
||||||
@SerializedName("poster_path") override val posterPath: String?,
|
@SerializedName("poster_path") override val posterPath: String?,
|
||||||
@SerializedName("name") val name: String
|
@SerializedName("name") val name: String,
|
||||||
): MediaItem(posterPath, name)
|
@SerializedName("id") override val id: Int
|
||||||
|
): MediaItem(posterPath, name, id)
|
||||||
@@ -17,6 +17,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.navigation.NavController
|
||||||
import coil.compose.rememberImagePainter
|
import coil.compose.rememberImagePainter
|
||||||
import coil.transform.RoundedCornersTransformation
|
import coil.transform.RoundedCornersTransformation
|
||||||
import com.owenlejeune.tvtime.R
|
import com.owenlejeune.tvtime.R
|
||||||
@@ -24,10 +25,14 @@ import com.owenlejeune.tvtime.api.tmdb.TmdbUtils
|
|||||||
import com.owenlejeune.tvtime.api.tmdb.model.MediaItem
|
import com.owenlejeune.tvtime.api.tmdb.model.MediaItem
|
||||||
import com.owenlejeune.tvtime.extensions.dpToPx
|
import com.owenlejeune.tvtime.extensions.dpToPx
|
||||||
import com.owenlejeune.tvtime.extensions.listItems
|
import com.owenlejeune.tvtime.extensions.listItems
|
||||||
|
import com.owenlejeune.tvtime.ui.navigation.MainNavItem
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun PosterGrid(fetchMedia: (MutableState<List<MediaItem>>) -> Unit) {
|
fun PosterGrid(
|
||||||
|
appNavController: NavController,
|
||||||
|
fetchMedia: (MutableState<List<MediaItem>>) -> Unit
|
||||||
|
) {
|
||||||
val mediaList = remember { mutableStateOf(emptyList<MediaItem>()) }
|
val mediaList = remember { mutableStateOf(emptyList<MediaItem>()) }
|
||||||
fetchMedia(mediaList)
|
fetchMedia(mediaList)
|
||||||
|
|
||||||
@@ -36,13 +41,16 @@ fun PosterGrid(fetchMedia: (MutableState<List<MediaItem>>) -> Unit) {
|
|||||||
contentPadding = PaddingValues(8.dp)
|
contentPadding = PaddingValues(8.dp)
|
||||||
) {
|
) {
|
||||||
listItems(mediaList.value) { item ->
|
listItems(mediaList.value) { item ->
|
||||||
PosterItem(mediaItem = item)
|
PosterItem(appNavController = appNavController, mediaItem = item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PosterItem(mediaItem: MediaItem) {
|
fun PosterItem(
|
||||||
|
appNavController: NavController,
|
||||||
|
mediaItem: MediaItem
|
||||||
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val poster = TmdbUtils.getFullPosterPath(mediaItem)
|
val poster = TmdbUtils.getFullPosterPath(mediaItem)
|
||||||
Image(
|
Image(
|
||||||
@@ -58,18 +66,11 @@ fun PosterItem(mediaItem: MediaItem) {
|
|||||||
.size(190.dp)
|
.size(190.dp)
|
||||||
.padding(5.dp)
|
.padding(5.dp)
|
||||||
.clickable {
|
.clickable {
|
||||||
Toast
|
appNavController.navigate("${MainNavItem.DetailView.route}/${mediaItem.id}")
|
||||||
.makeText(context, "${mediaItem.title} clicked", Toast.LENGTH_SHORT)
|
// appNavController.n
|
||||||
.show()
|
// Toast
|
||||||
|
// .makeText(context, "${mediaItem.title} clicked", Toast.LENGTH_SHORT)
|
||||||
|
// .show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
fun PosterItemPreview() {
|
|
||||||
PosterItem(mediaItem = object : MediaItem(
|
|
||||||
title = "Deadpool",
|
|
||||||
posterPath = "/fSRb7vyIP8rQpL0I47P3qUsEKX3.jpg"
|
|
||||||
){})
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,17 @@
|
|||||||
package com.owenlejeune.tvtime.ui.navigation
|
package com.owenlejeune.tvtime.ui.navigation
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.navigation.NavType
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
|
import androidx.navigation.navArgument
|
||||||
import com.owenlejeune.tvtime.ui.screens.*
|
import com.owenlejeune.tvtime.ui.screens.*
|
||||||
|
import com.owenlejeune.tvtime.ui.screens.tabs.FavouritesTab
|
||||||
|
import com.owenlejeune.tvtime.ui.screens.tabs.MoviesTab
|
||||||
|
import com.owenlejeune.tvtime.ui.screens.tabs.SettingsTab
|
||||||
|
import com.owenlejeune.tvtime.ui.screens.tabs.TvTab
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainNavigationRoutes(navController: NavHostController) {
|
fun MainNavigationRoutes(navController: NavHostController) {
|
||||||
@@ -12,20 +19,30 @@ fun MainNavigationRoutes(navController: NavHostController) {
|
|||||||
composable(MainNavItem.MainView.route) {
|
composable(MainNavItem.MainView.route) {
|
||||||
MainAppView(appNavController = navController)
|
MainAppView(appNavController = navController)
|
||||||
}
|
}
|
||||||
composable(MainNavItem.DetailView.route) {
|
composable(
|
||||||
|
MainNavItem.DetailView.route.plus("/{ID_KEY}"),
|
||||||
|
arguments = listOf(navArgument("ID_KEY") { type = NavType.IntType })
|
||||||
|
) { navBackStackEntry ->
|
||||||
|
val args = navBackStackEntry.arguments
|
||||||
|
DetailView(
|
||||||
|
appNavController = navController,
|
||||||
|
itemId = navBackStackEntry.arguments?.getInt("ID_KEY")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomNavigationRoutes(navController: NavHostController) {
|
fun BottomNavigationRoutes(
|
||||||
|
appNavController: NavController,
|
||||||
|
navController: NavHostController
|
||||||
|
) {
|
||||||
NavHost(navController = navController, startDestination = BottomNavItem.Movies.route) {
|
NavHost(navController = navController, startDestination = BottomNavItem.Movies.route) {
|
||||||
composable(BottomNavItem.Movies.route) {
|
composable(BottomNavItem.Movies.route) {
|
||||||
MoviesTab()
|
MoviesTab(appNavController = appNavController)
|
||||||
}
|
}
|
||||||
composable(BottomNavItem.TV.route) {
|
composable(BottomNavItem.TV.route) {
|
||||||
TvTab()
|
TvTab(appNavController = appNavController)
|
||||||
}
|
}
|
||||||
composable(BottomNavItem.Favourites.route) {
|
composable(BottomNavItem.Favourites.route) {
|
||||||
FavouritesTab()
|
FavouritesTab()
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.owenlejeune.tvtime.ui.screens
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.wrapContentSize
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DetailView(
|
||||||
|
appNavController: NavController,
|
||||||
|
itemId: Int?
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.wrapContentSize(Alignment.Center)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = itemId.toString(),
|
||||||
|
color = MaterialTheme.colorScheme.onBackground
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,7 +51,7 @@ fun MainAppView(appNavController: NavController) {
|
|||||||
}
|
}
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
Box(modifier = Modifier.padding(innerPadding)) {
|
Box(modifier = Modifier.padding(innerPadding)) {
|
||||||
BottomNavigationRoutes(navController = navController)
|
BottomNavigationRoutes(appNavController = appNavController, navController = navController)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.owenlejeune.tvtime.ui.screens
|
package com.owenlejeune.tvtime.ui.screens.tabs
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
package com.owenlejeune.tvtime.ui.screens
|
package com.owenlejeune.tvtime.ui.screens.tabs
|
||||||
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.navigation.NavController
|
||||||
import com.owenlejeune.tvtime.api.tmdb.MoviesService
|
import com.owenlejeune.tvtime.api.tmdb.MoviesService
|
||||||
import com.owenlejeune.tvtime.ui.components.PosterGrid
|
import com.owenlejeune.tvtime.ui.components.PosterGrid
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun MoviesTab() {
|
fun MoviesTab(appNavController: NavController) {
|
||||||
// val moviesViewModel = viewModel(PopularMovieViewModel::class.java)
|
// val moviesViewModel = viewModel(PopularMovieViewModel::class.java)
|
||||||
// val moviesList = moviesViewModel.moviePage
|
// val moviesList = moviesViewModel.moviePage
|
||||||
// val movieListItems: LazyPagingItems<PopularMovie> = moviesList.collectAsLazyPagingItems()
|
// val movieListItems: LazyPagingItems<PopularMovie> = moviesList.collectAsLazyPagingItems()
|
||||||
PosterGrid { moviesList ->
|
PosterGrid(appNavController = appNavController) { moviesList ->
|
||||||
val service = MoviesService()
|
val service = MoviesService()
|
||||||
service.getPopularMovies { isSuccessful, response ->
|
service.getPopularMovies { isSuccessful, response ->
|
||||||
if (isSuccessful) {
|
if (isSuccessful) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.owenlejeune.tvtime.ui.screens
|
package com.owenlejeune.tvtime.ui.screens.tabs
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
package com.owenlejeune.tvtime.ui.screens
|
package com.owenlejeune.tvtime.ui.screens.tabs
|
||||||
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.navigation.NavController
|
||||||
import com.owenlejeune.tvtime.api.tmdb.TvService
|
import com.owenlejeune.tvtime.api.tmdb.TvService
|
||||||
import com.owenlejeune.tvtime.ui.components.PosterGrid
|
import com.owenlejeune.tvtime.ui.components.PosterGrid
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun TvTab() {
|
fun TvTab(appNavController: NavController) {
|
||||||
PosterGrid { tvList ->
|
PosterGrid(appNavController = appNavController) { tvList ->
|
||||||
val service = TvService()
|
val service = TvService()
|
||||||
service.getPopularTv { isSuccessful, response ->
|
service.getPopularTv { isSuccessful, response ->
|
||||||
if (isSuccessful) {
|
if (isSuccessful) {
|
||||||
|
|||||||
Reference in New Issue
Block a user