From 88675d3832d692ff7f6a3d584c7fc2c8cc3a4818 Mon Sep 17 00:00:00 2001 From: Owen LeJeune Date: Sat, 5 Nov 2022 21:38:03 -0400 Subject: [PATCH] refactor search views --- .../tvtime/ui/screens/SearchScreen.kt | 74 ++-------- .../tvtime/ui/screens/main/AccountTab.kt | 111 ++------------ .../tvtime/ui/screens/main/MediaViews.kt | 135 ++++++++++++++++++ 3 files changed, 155 insertions(+), 165 deletions(-) create mode 100644 app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViews.kt diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/SearchScreen.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/SearchScreen.kt index 66c74c6..7ea3193 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/SearchScreen.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/SearchScreen.kt @@ -33,6 +33,7 @@ import com.owenlejeune.tvtime.api.tmdb.api.v3.TvService import com.owenlejeune.tvtime.api.tmdb.api.v3.model.* import com.owenlejeune.tvtime.extensions.listItems import com.owenlejeune.tvtime.ui.navigation.MainNavItem +import com.owenlejeune.tvtime.ui.screens.main.MediaResultCard import com.owenlejeune.tvtime.ui.screens.main.MediaViewType import com.owenlejeune.tvtime.utils.TmdbUtils import kotlinx.coroutines.CoroutineScope @@ -221,70 +222,15 @@ private fun SearchResultItemView( backdropModel: (T) -> Any?, additionalDetails: (T) -> List = { emptyList() } ) { - Card( - modifier = Modifier - .fillMaxWidth() - .clickable( - onClick = { - appNavController.navigate("${MainNavItem.DetailView.route}/${mediaViewType}/${searchResult.id}") - } - ), - shape = RoundedCornerShape(10.dp), - elevation = 8.dp - ) { - Box( - modifier = Modifier.height(112.dp) - ) { - AsyncImage( - model = backdropModel(searchResult), - contentDescription = null, - contentScale = ContentScale.FillWidth, - modifier = Modifier - .blur(radius = 10.dp) - .fillMaxWidth() - ) - - Box(modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(alpha = 0.7f)) - .blur(radius = 10.dp) - ) - - Row( - modifier = Modifier.padding(8.dp) - ) { - AsyncImage( - model = posterModel(searchResult), - contentDescription = null, - modifier = Modifier - .padding(end = 8.dp) - .size(width = 75.dp, height = 112.dp) - ) - - Column( - verticalArrangement = Arrangement.spacedBy(4.dp), - modifier = Modifier - .align(Alignment.CenterVertically) - ) { - Text( - text = searchResult.name, - color = MaterialTheme.colorScheme.onBackground, - fontSize = 18.sp - ) - - additionalDetails(searchResult) - .filter { it.isNotEmpty() } - .forEach { item -> - Text( - text = item, - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontSize = 16.sp - ) - } - } - } - } - } + MediaResultCard( + appNavController = appNavController, + mediaViewType = mediaViewType, + id = searchResult.id, + backdropPath = backdropModel(searchResult), + posterPath = posterModel(searchResult), + title = searchResult.name, + additionalDetails = additionalDetails(searchResult) + ) } @Composable diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/AccountTab.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/AccountTab.kt index ee70819..aaf73a8 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/AccountTab.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/AccountTab.kt @@ -254,107 +254,16 @@ private fun MediaItemRow( backdropPath: String? = null, rating: Float? = null ) { - Card( - shape = RoundedCornerShape(10.dp), - elevation = CardDefaults.cardElevation(defaultElevation = 10.dp), - modifier = Modifier - .background(color = MaterialTheme.colorScheme.surface) - .fillMaxWidth() - .clickable( - onClick = { - appNavController.navigate( - "${MainNavItem.DetailView.route}/${mediaViewType}/${id}" - ) - } - ) - ) { - Box( - modifier = Modifier - .height(112.dp) - ) { - AsyncImage( - model = backdropPath, - contentDescription = null, - contentScale = ContentScale.FillWidth, - modifier = Modifier - .blur(radius = 10.dp) - .fillMaxWidth() - .wrapContentHeight() - ) - - backdropPath?.let { - Box(modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(alpha = 0.7f)) - .blur(radius = 10.dp) - ) - } - - ConstraintLayout( - modifier = Modifier - .padding(8.dp) - .fillMaxSize() - ) { - val (poster, content, ratingView) = createRefs() - - AsyncImage( - modifier = Modifier - .constrainAs(poster) { - start.linkTo(parent.start) - top.linkTo(parent.top) - bottom.linkTo(parent.bottom) - height = Dimension.fillToConstraints - } - .clip(RoundedCornerShape(10.dp)), - model = posterPath, - contentDescription = "", - ) - - Column( - verticalArrangement = Arrangement.spacedBy(4.dp), - modifier = Modifier - .constrainAs(content) { - end.linkTo( - rating?.let { ratingView.start } ?: parent.end, - margin = 8.dp - ) - start.linkTo(poster.end, margin = 8.dp) - top.linkTo(parent.top) - bottom.linkTo(parent.bottom) - width = Dimension.fillToConstraints - height = Dimension.fillToConstraints - } - ) { - val releaseYear = date.split("-")[0] - Text( - text = "$name (${releaseYear})", - color = MaterialTheme.colorScheme.onBackground, - fontSize = 18.sp, - fontWeight = FontWeight.Bold - ) - - Text( - text = description, - color = MaterialTheme.colorScheme.onBackground, - fontSize = 14.sp, - overflow = TextOverflow.Ellipsis - ) - } - - rating?.let { - RatingView( - progress = rating/10, - modifier = Modifier - .constrainAs(ratingView) { - end.linkTo(parent.end) - top.linkTo(parent.top) - bottom.linkTo(parent.bottom) - } - ) - } - } - } - } + MediaResultCard( + appNavController = appNavController, + mediaViewType = mediaViewType, + id = id, + backdropPath = backdropPath, + posterPath = posterPath, + title = "$name (${date.split("-")[0]})", + additionalDetails = listOf(description), + rating = rating + ) } @Composable diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViews.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViews.kt new file mode 100644 index 0000000..9219ee5 --- /dev/null +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViews.kt @@ -0,0 +1,135 @@ +package com.owenlejeune.tvtime.ui.screens.main + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.blur +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.constraintlayout.compose.ConstraintLayout +import androidx.constraintlayout.compose.Dimension +import androidx.navigation.NavController +import coil.compose.AsyncImage +import com.owenlejeune.tvtime.ui.navigation.MainNavItem + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MediaResultCard( + appNavController: NavController, + mediaViewType: MediaViewType, + id: Int, + backdropPath: Any?, + posterPath: Any?, + title: String, + additionalDetails: List, + rating: Float? = null +) { + Card( + shape = RoundedCornerShape(10.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 10.dp), + modifier = Modifier + .background(color = MaterialTheme.colorScheme.surface) + .fillMaxWidth() + .clickable( + onClick = { + appNavController.navigate( + "${MainNavItem.DetailView.route}/${mediaViewType}/${id}" + ) + } + ) + ) { + Box( + modifier = Modifier.height(112.dp) + ) { + backdropPath?.let { + AsyncImage( + model = backdropPath, + contentDescription = null, + contentScale = ContentScale.FillWidth, + modifier = Modifier + .blur(radius = 10.dp) + .fillMaxWidth() + .wrapContentHeight() + ) + + Box(modifier = Modifier + .fillMaxSize() + .background(Color.Black.copy(alpha = 0.7f)) + .blur(radius = 10.dp) + ) + } + + ConstraintLayout( + modifier = Modifier + .padding(8.dp) + .fillMaxSize() + ) { + val (poster, content, ratingView) = createRefs() + + AsyncImage( + modifier = Modifier + .constrainAs(poster) { + start.linkTo(parent.start) + top.linkTo(parent.top) + bottom.linkTo(parent.bottom) + height = Dimension.fillToConstraints + } + .clip(RoundedCornerShape(10.dp)), + model = posterPath, + contentDescription = title + ) + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + modifier = Modifier + .constrainAs(content) { + end.linkTo( + rating?.let { ratingView.start } ?: parent.end, + margin = 12.dp + ) + start.linkTo(poster.end, margin = 12.dp) + width = Dimension.fillToConstraints + height = Dimension.matchParent + } + ) { + Text( + text = title, + color = MaterialTheme.colorScheme.onBackground, + fontSize = 18.sp, + fontWeight = FontWeight.Bold + ) + + additionalDetails.forEach { + Text( + text = it, + color = MaterialTheme.colorScheme.onBackground, + fontSize = 14.sp, + overflow = TextOverflow.Ellipsis + ) + } + } + + rating?.let { + RatingView( + progress = rating / 10f, + modifier = Modifier + .constrainAs(ratingView) { + end.linkTo(parent.end) + top.linkTo(parent.top) + bottom.linkTo(parent.bottom) + } + ) + } + } + } + } +} \ No newline at end of file