add paging for home page people and option to show titles on home page posters

This commit is contained in:
Owen LeJeune
2022-11-07 10:47:42 -05:00
parent 88675d3832
commit fe0b0538bd
8 changed files with 91 additions and 45 deletions

View File

@@ -35,7 +35,7 @@ class HomePagePagingSource(
nextKey = if (results.isEmpty() || responseBody == null) null else responseBody.page + 1 nextKey = if (results.isEmpty() || responseBody == null) null else responseBody.page + 1
) )
} else { } else {
Toast.makeText(context, "No more results found", Toast.LENGTH_SHORT).show() // Toast.makeText(context, "No more results found", Toast.LENGTH_SHORT).show()
LoadResult.Invalid() LoadResult.Invalid()
} }
} catch (e: Exception) { } catch (e: Exception) {

View File

@@ -32,7 +32,7 @@ class HomePagePeoplePagingSource: PagingSource<Int, HomePagePerson>(), KoinCompo
nextKey = if (results.isEmpty() || responseBody == null) null else responseBody.page + 1 nextKey = if (results.isEmpty() || responseBody == null) null else responseBody.page + 1
) )
} else { } else {
Toast.makeText(context, "No more results found", Toast.LENGTH_SHORT).show() // Toast.makeText(context, "No more results found", Toast.LENGTH_SHORT).show()
LoadResult.Invalid() LoadResult.Invalid()
} }
} catch (e: Exception) { } catch (e: Exception) {

View File

@@ -4,7 +4,6 @@ import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import com.google.gson.Gson import com.google.gson.Gson
import com.kieronquinn.monetcompat.core.MonetCompat import com.kieronquinn.monetcompat.core.MonetCompat
import com.owenlejeune.tvtime.BuildConfig
import com.owenlejeune.tvtime.utils.SessionManager import com.owenlejeune.tvtime.utils.SessionManager
class AppPreferences(context: Context) { class AppPreferences(context: Context) {
@@ -37,6 +36,7 @@ class AppPreferences(context: Context) {
private val PEOPLE_TAB_POSITION = "people_tab_position" private val PEOPLE_TAB_POSITION = "people_tab_position"
private val ACCOUNT_TAB_POSITION = "account_tab_position" private val ACCOUNT_TAB_POSITION = "account_tab_position"
private val SHOW_BTAB_LABELS = "show_btab_labels" private val SHOW_BTAB_LABELS = "show_btab_labels"
private val SHOW_POSTER_TITLE = "show_poster_titles"
} }
private val preferences: SharedPreferences = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE) private val preferences: SharedPreferences = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE)
@@ -119,6 +119,11 @@ class AppPreferences(context: Context) {
get() = preferences.getBoolean(SHOW_BTAB_LABELS, showBottomTabLabelsDefault) get() = preferences.getBoolean(SHOW_BTAB_LABELS, showBottomTabLabelsDefault)
set(value) { preferences.put(SHOW_BTAB_LABELS, value) } set(value) { preferences.put(SHOW_BTAB_LABELS, value) }
val showPosterTitlesDefault: Boolean = false
var showPosterTitles: Boolean
get() = preferences.getBoolean(SHOW_POSTER_TITLE, showPosterTitlesDefault)
set(value) { preferences.put(SHOW_POSTER_TITLE, value) }
/******** Dev Preferences ********/ /******** Dev Preferences ********/
val firstLaunchTestingDefault: Boolean = false val firstLaunchTestingDefault: Boolean = false
var firstLaunchTesting: Boolean var firstLaunchTesting: Boolean

View File

@@ -149,7 +149,7 @@ fun TwoLineImageTextCard(
url = imageUrl, url = imageUrl,
noDataImage = noDataImage, noDataImage = noDataImage,
placeholder = placeholder, placeholder = placeholder,
contentDescription = title, title = title,
elevation = 0.dp elevation = 0.dp
) )
MinLinesText( MinLinesText(

View File

@@ -1,6 +1,5 @@
package com.owenlejeune.tvtime.ui.components package com.owenlejeune.tvtime.ui.components
import android.annotation.SuppressLint
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
@@ -11,14 +10,16 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card import androidx.compose.material.Card
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -26,19 +27,16 @@ import androidx.paging.LoadState
import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.LazyPagingItems
import coil.compose.AsyncImage import coil.compose.AsyncImage
import coil.compose.rememberAsyncImagePainter import coil.compose.rememberAsyncImagePainter
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.HorizontalPager
import com.google.accompanist.pager.rememberPagerState
import com.owenlejeune.tvtime.R import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.HomePagePerson import com.owenlejeune.tvtime.api.tmdb.api.v3.model.HomePagePerson
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ImageCollection
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.Person import com.owenlejeune.tvtime.api.tmdb.api.v3.model.Person
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.TmdbItem import com.owenlejeune.tvtime.api.tmdb.api.v3.model.TmdbItem
import com.owenlejeune.tvtime.extensions.dpToPx
import com.owenlejeune.tvtime.extensions.header import com.owenlejeune.tvtime.extensions.header
import com.owenlejeune.tvtime.extensions.lazyPagingItems import com.owenlejeune.tvtime.extensions.lazyPagingItems
import com.owenlejeune.tvtime.extensions.listItems import com.owenlejeune.tvtime.extensions.listItems
import com.owenlejeune.tvtime.preferences.AppPreferences
import com.owenlejeune.tvtime.utils.TmdbUtils import com.owenlejeune.tvtime.utils.TmdbUtils
import org.koin.java.KoinJavaComponent.get
private val POSTER_WIDTH = 120.dp private val POSTER_WIDTH = 120.dp
private val POSTER_HEIGHT = 190.dp private val POSTER_HEIGHT = 190.dp
@@ -122,7 +120,7 @@ fun PagingPeoplePosterGrid(
onClick = { onClick = {
onClick(person.id) onClick(person.id)
}, },
contentDescription = person.name title = person.name
) )
} }
} }
@@ -159,7 +157,7 @@ fun PeoplePosterGrid(
onClick = { onClick = {
onClick(person.id) onClick(person.id)
}, },
contentDescription = person.name title = person.name
) )
} }
} }
@@ -185,7 +183,7 @@ fun PosterItem(
}, },
url = mediaItem?.let { TmdbUtils.getFullPosterPath(mediaItem) }, url = mediaItem?.let { TmdbUtils.getFullPosterPath(mediaItem) },
elevation = elevation, elevation = elevation,
contentDescription = mediaItem?.title title = mediaItem?.title
) )
} }
@@ -209,7 +207,7 @@ fun PosterItem(
}, },
url = person?.let { TmdbUtils.getFullPersonImagePath(person) }, url = person?.let { TmdbUtils.getFullPersonImagePath(person) },
elevation = 8.dp, elevation = 8.dp,
contentDescription = person?.name title = person?.name
) )
} }
@@ -223,7 +221,8 @@ fun PosterItem(
noDataImage: Int = R.drawable.placeholder, noDataImage: Int = R.drawable.placeholder,
placeholder: Int = R.drawable.placeholder, placeholder: Int = R.drawable.placeholder,
elevation: Dp = 8.dp, elevation: Dp = 8.dp,
contentDescription: String? title: String?,
preferences: AppPreferences = get(AppPreferences::class.java)
) { ) {
Card( Card(
elevation = elevation, elevation = elevation,
@@ -232,31 +231,64 @@ fun PosterItem(
.wrapContentHeight(), .wrapContentHeight(),
shape = RoundedCornerShape(5.dp) shape = RoundedCornerShape(5.dp)
) { ) {
if (url != null) { Box {
AsyncImage( var sizeImage by remember { mutableStateOf(IntSize.Zero) }
modifier = Modifier val gradient = Brush.verticalGradient(
.width(width = width) colors = listOf(Color.Transparent, Color.Black.copy(alpha = 0.7f)),
.clip(RoundedCornerShape(5.dp)) startY = sizeImage.height.toFloat() / 3f,
.clickable( endY = sizeImage.height.toFloat()
onClick = onClick
),
model = url,
placeholder = rememberAsyncImagePainter(model = placeholder),
contentDescription = contentDescription,
contentScale = ContentScale.FillWidth
)
} else {
Image(
modifier = Modifier
.size(width = width, height = height)
.clip(RoundedCornerShape(5.dp))
.clickable(
onClick = onClick
),
painter = rememberAsyncImagePainter(model = noDataImage),
contentDescription = contentDescription,
contentScale = ContentScale.FillBounds
) )
if (url != null) {
AsyncImage(
modifier = Modifier
.width(width = width)
.wrapContentHeight()
.clip(RoundedCornerShape(5.dp))
.clickable(
onClick = onClick
)
.onGloballyPositioned { sizeImage = it.size },
model = url,
placeholder = rememberAsyncImagePainter(model = placeholder),
contentDescription = title,
contentScale = ContentScale.FillWidth
)
} else {
Image(
modifier = Modifier
.width(width = width)
.wrapContentHeight()
.clip(RoundedCornerShape(5.dp))
.clickable(
onClick = onClick
)
.onGloballyPositioned { sizeImage = it.size },
painter = rememberAsyncImagePainter(model = noDataImage),
contentDescription = title,
contentScale = ContentScale.FillBounds
)
}
if (preferences.showPosterTitles) {
title?.let {
Box(
modifier = Modifier
.clip(RoundedCornerShape(5.dp))
.background(brush = gradient)
.matchParentSize()
)
Text(
text = title,
modifier = Modifier
.align(Alignment.BottomStart)
.padding(6.dp),
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onBackground
)
}
}
} }
} }
} }

View File

@@ -1,7 +1,5 @@
package com.owenlejeune.tvtime.ui.screens.main package com.owenlejeune.tvtime.ui.screens.main
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
@@ -25,13 +23,11 @@ import com.google.accompanist.pager.HorizontalPager
import com.google.accompanist.pager.rememberPagerState import com.google.accompanist.pager.rememberPagerState
import com.owenlejeune.tvtime.R import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ImageCollection import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ImageCollection
import com.owenlejeune.tvtime.preferences.AppPreferences
import com.owenlejeune.tvtime.ui.components.PosterItem import com.owenlejeune.tvtime.ui.components.PosterItem
import com.owenlejeune.tvtime.ui.components.RatingRing import com.owenlejeune.tvtime.ui.components.RatingRing
import com.owenlejeune.tvtime.utils.TmdbUtils import com.owenlejeune.tvtime.utils.TmdbUtils
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.java.KoinJavaComponent.get
@Composable @Composable
fun DetailHeader( fun DetailHeader(
@@ -75,7 +71,7 @@ fun DetailHeader(
start.linkTo(parent.start, margin = 16.dp) start.linkTo(parent.start, margin = 16.dp)
}, },
url = posterUrl, url = posterUrl,
contentDescription = posterContentDescription, title = posterContentDescription,
elevation = 20.dp elevation = 20.dp
) )

View File

@@ -378,6 +378,17 @@ private fun HomeScreenPreferences(
} }
) )
val showPosterTitles = remember { mutableStateOf(preferences.showPosterTitles) }
SwitchPreference(
titleText = stringResource(R.string.preference_show_poster_titles_title),
subtitleText = stringResource(R.string.preference_show_poster_titles_subtitle),
checkState = showTabLabels.value,
onCheckedChange = { isChecked ->
showPosterTitles.value = isChecked
preferences.showPosterTitles = isChecked
}
)
PreferenceHeading(text = stringResource(R.string.preference_home_tab_order_heading)) PreferenceHeading(text = stringResource(R.string.preference_home_tab_order_heading))
Box(modifier = Modifier Box(modifier = Modifier

View File

@@ -151,4 +151,6 @@
<string name="action_skip">Skip</string> <string name="action_skip">Skip</string>
<string name="action_skip_testing">Skip (t)</string> <string name="action_skip_testing">Skip (t)</string>
<string name="popular_today_header">Popular Today</string> <string name="popular_today_header">Popular Today</string>
<string name="preference_show_poster_titles_title">Show Poster Titles</string>
<string name="preference_show_poster_titles_subtitle">Show titles on home screen posters</string>
</resources> </resources>