mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-09 13:22:44 -05:00
add images to profile details
This commit is contained in:
@@ -7,7 +7,6 @@ import com.owenlejeune.tvtime.api.tmdb.api.v3.model.PersonCreditsResponse
|
|||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.PersonImageCollection
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.PersonImageCollection
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.SearchResult
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.SearchResult
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.SearchResultPerson
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.SearchResultPerson
|
||||||
import com.owenlejeune.tvtime.utils.types.TimeWindow
|
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
import retrofit2.http.Path
|
import retrofit2.http.Path
|
||||||
@@ -18,12 +17,6 @@ interface PeopleApi {
|
|||||||
@GET("person/{id}")
|
@GET("person/{id}")
|
||||||
suspend fun getPerson(@Path("id") id: Int): Response<DetailPerson>
|
suspend fun getPerson(@Path("id") id: Int): Response<DetailPerson>
|
||||||
|
|
||||||
// @GET("person/{id}/movie_credits")
|
|
||||||
// suspend fun getMovieCredits(@Path("id") id: Int)
|
|
||||||
//
|
|
||||||
// @GET("person/{id}/tv_credits")
|
|
||||||
// suspend fun getTvCredits(@Path("id") id: Int)
|
|
||||||
|
|
||||||
@GET("person/{id}/combined_credits")
|
@GET("person/{id}/combined_credits")
|
||||||
suspend fun getCredits(@Path("id") id: Int): Response<PersonCreditsResponse>
|
suspend fun getCredits(@Path("id") id: Int): Response<PersonCreditsResponse>
|
||||||
|
|
||||||
@@ -40,6 +33,6 @@ interface PeopleApi {
|
|||||||
suspend fun getExternalIds(@Path("id") id: Int): Response<ExternalIds>
|
suspend fun getExternalIds(@Path("id") id: Int): Response<ExternalIds>
|
||||||
|
|
||||||
@GET("trending/person/{time_window}")
|
@GET("trending/person/{time_window}")
|
||||||
suspend fun trending(@Path("time_window") timeWindow: String, @Query("page") page: Int): Response<SearchResult<SearchResultPerson>>
|
suspend fun getTrending(@Path("time_window") timeWindow: String, @Query("page") page: Int): Response<SearchResult<SearchResultPerson>>
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6,17 +6,12 @@ import com.owenlejeune.tvtime.api.tmdb.TmdbClient
|
|||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailCast
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailCast
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailCrew
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailCrew
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailPerson
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailPerson
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailedMovie
|
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ExternalIds
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ExternalIds
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.HomePagePeopleResponse
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.HomePagePeopleResponse
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.PersonCreditsResponse
|
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.PersonImage
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.PersonImage
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.PersonImageCollection
|
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.SearchResult
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.SearchResult
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.SearchResultMedia
|
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.SearchResultPerson
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.SearchResultPerson
|
||||||
import com.owenlejeune.tvtime.utils.types.TimeWindow
|
import com.owenlejeune.tvtime.utils.types.TimeWindow
|
||||||
import okhttp3.internal.notify
|
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
@@ -95,7 +90,7 @@ class PeopleService: KoinComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getTrending(timeWindow: TimeWindow, page: Int): Response<SearchResult<SearchResultPerson>> {
|
suspend fun getTrending(timeWindow: TimeWindow, page: Int): Response<SearchResult<SearchResultPerson>> {
|
||||||
return service.trending(timeWindow.name.lowercase(), page)
|
return service.getTrending(timeWindow.name.lowercase(), page)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,7 @@ import com.owenlejeune.tvtime.extensions.safeGetSerializable
|
|||||||
import com.owenlejeune.tvtime.preferences.AppPreferences
|
import com.owenlejeune.tvtime.preferences.AppPreferences
|
||||||
import com.owenlejeune.tvtime.ui.screens.AboutScreen
|
import com.owenlejeune.tvtime.ui.screens.AboutScreen
|
||||||
import com.owenlejeune.tvtime.ui.screens.AccountScreen
|
import com.owenlejeune.tvtime.ui.screens.AccountScreen
|
||||||
|
import com.owenlejeune.tvtime.ui.screens.GalleryView
|
||||||
import com.owenlejeune.tvtime.ui.screens.HomeScreen
|
import com.owenlejeune.tvtime.ui.screens.HomeScreen
|
||||||
import com.owenlejeune.tvtime.ui.screens.KeywordResultsScreen
|
import com.owenlejeune.tvtime.ui.screens.KeywordResultsScreen
|
||||||
import com.owenlejeune.tvtime.ui.screens.KnownForScreen
|
import com.owenlejeune.tvtime.ui.screens.KnownForScreen
|
||||||
@@ -187,6 +188,18 @@ fun AppNavigationHost(
|
|||||||
|
|
||||||
KnownForScreen(appNavController = appNavController, id = id)
|
KnownForScreen(appNavController = appNavController, id = id)
|
||||||
}
|
}
|
||||||
|
composable(
|
||||||
|
route = AppNavItem.GalleryView.route.plus("/{${NavConstants.TYPE_KEY}}/{${NavConstants.ID_KEY}}"),
|
||||||
|
arguments = listOf(
|
||||||
|
navArgument(NavConstants.TYPE_KEY) { type = NavType.EnumType(MediaViewType::class.java) },
|
||||||
|
navArgument(NavConstants.ID_KEY) { type = NavType.IntType }
|
||||||
|
)
|
||||||
|
) { navBackStackEntry ->
|
||||||
|
val type = navBackStackEntry.arguments?.safeGetSerializable(NavConstants.TYPE_KEY, MediaViewType::class.java)!!
|
||||||
|
val id = navBackStackEntry.arguments?.getInt(NavConstants.ID_KEY)!!
|
||||||
|
|
||||||
|
GalleryView(id = id, type = type, appNavController = appNavController)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,5 +230,8 @@ sealed class AppNavItem(val route: String) {
|
|||||||
object KnownForView: AppNavItem("known_for_route") {
|
object KnownForView: AppNavItem("known_for_route") {
|
||||||
fun withArgs(id: Int) = route.plus("/$id")
|
fun withArgs(id: Int) = route.plus("/$id")
|
||||||
}
|
}
|
||||||
|
object GalleryView: AppNavItem("gallery_view_route") {
|
||||||
|
fun withArgs(type: MediaViewType, id: Int) = route.plus("/$type/$id")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package com.owenlejeune.tvtime.ui.screens
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.grid.GridCells
|
||||||
|
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||||
|
import androidx.compose.foundation.lazy.grid.items
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.filled.Person
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
|
import androidx.compose.material3.rememberTopAppBarState
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
|
import com.owenlejeune.tvtime.R
|
||||||
|
import com.owenlejeune.tvtime.ui.components.PosterItem
|
||||||
|
import com.owenlejeune.tvtime.ui.viewmodel.MainViewModel
|
||||||
|
import com.owenlejeune.tvtime.utils.TmdbUtils
|
||||||
|
import com.owenlejeune.tvtime.utils.types.MediaViewType
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun GalleryView(
|
||||||
|
id: Int,
|
||||||
|
type: MediaViewType,
|
||||||
|
appNavController: NavController
|
||||||
|
) {
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
systemUiController.setStatusBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
systemUiController.setNavigationBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
|
||||||
|
val topAppBarScrollState = rememberTopAppBarState()
|
||||||
|
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(topAppBarScrollState)
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
|
topBar = {
|
||||||
|
TopAppBar(
|
||||||
|
scrollBehavior = scrollBehavior,
|
||||||
|
colors = TopAppBarDefaults
|
||||||
|
.topAppBarColors(
|
||||||
|
scrolledContainerColor = MaterialTheme.colorScheme.background,
|
||||||
|
titleContentColor = MaterialTheme.colorScheme.primary
|
||||||
|
),
|
||||||
|
title = { Text(text = "Images") },
|
||||||
|
navigationIcon = {
|
||||||
|
IconButton(onClick = { appNavController.popBackStack() }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.ArrowBack,
|
||||||
|
contentDescription = stringResource(id = R.string.content_description_back_button),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { innerPadding ->
|
||||||
|
Box(modifier = Modifier.padding(innerPadding)) {
|
||||||
|
when (type) {
|
||||||
|
MediaViewType.PERSON -> PersonGalleryView(id = id)
|
||||||
|
MediaViewType.TV,
|
||||||
|
MediaViewType.MOVIE -> MediaGalleryView(id = id, type = type)
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun MediaGalleryView(
|
||||||
|
id: Int,
|
||||||
|
type: MediaViewType
|
||||||
|
) {
|
||||||
|
// todo - add support for images
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun PersonGalleryView(
|
||||||
|
id: Int
|
||||||
|
) {
|
||||||
|
val mainViewModel = viewModel<MainViewModel>()
|
||||||
|
|
||||||
|
val imagesMap = remember { mainViewModel.peopleImagesMap }
|
||||||
|
val images = imagesMap[id] ?: emptyList()
|
||||||
|
|
||||||
|
LazyVerticalGrid(
|
||||||
|
columns = GridCells.Adaptive(minSize = 120.dp),
|
||||||
|
contentPadding = PaddingValues(8.dp),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
|
items(images) { image ->
|
||||||
|
PosterItem(
|
||||||
|
width = 120.dp,
|
||||||
|
url = TmdbUtils.getFullPersonImagePath(image.filePath),
|
||||||
|
placeholder = Icons.Filled.Person,
|
||||||
|
title = ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,15 +5,18 @@ import androidx.compose.foundation.clickable
|
|||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
import androidx.compose.foundation.lazy.LazyRow
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.filled.Person
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
@@ -42,6 +45,7 @@ import com.owenlejeune.tvtime.ui.components.ContentCard
|
|||||||
import com.owenlejeune.tvtime.ui.components.DetailHeader
|
import com.owenlejeune.tvtime.ui.components.DetailHeader
|
||||||
import com.owenlejeune.tvtime.ui.components.ExpandableContentCard
|
import com.owenlejeune.tvtime.ui.components.ExpandableContentCard
|
||||||
import com.owenlejeune.tvtime.ui.components.ExternalIdsArea
|
import com.owenlejeune.tvtime.ui.components.ExternalIdsArea
|
||||||
|
import com.owenlejeune.tvtime.ui.components.PosterItem
|
||||||
import com.owenlejeune.tvtime.ui.components.TwoLineImageTextCard
|
import com.owenlejeune.tvtime.ui.components.TwoLineImageTextCard
|
||||||
import com.owenlejeune.tvtime.ui.navigation.AppNavItem
|
import com.owenlejeune.tvtime.ui.navigation.AppNavItem
|
||||||
import com.owenlejeune.tvtime.ui.viewmodel.MainViewModel
|
import com.owenlejeune.tvtime.ui.viewmodel.MainViewModel
|
||||||
@@ -62,6 +66,7 @@ fun PersonDetailScreen(
|
|||||||
mainViewModel.getById(personId, MediaViewType.PERSON)
|
mainViewModel.getById(personId, MediaViewType.PERSON)
|
||||||
mainViewModel.getExternalIds(personId, MediaViewType.PERSON)
|
mainViewModel.getExternalIds(personId, MediaViewType.PERSON)
|
||||||
mainViewModel.getCastAndCrew(personId, MediaViewType.PERSON)
|
mainViewModel.getCastAndCrew(personId, MediaViewType.PERSON)
|
||||||
|
mainViewModel.getImages(personId, MediaViewType.PERSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
val systemUiController = rememberSystemUiController()
|
val systemUiController = rememberSystemUiController()
|
||||||
@@ -122,50 +127,9 @@ fun PersonDetailScreen(
|
|||||||
|
|
||||||
BiographyCard(person = person)
|
BiographyCard(person = person)
|
||||||
|
|
||||||
val creditsMap = remember { mainViewModel.peopleCastMap }
|
CreditsCard(personId = personId, appNavController = appNavController)
|
||||||
val credits = creditsMap[personId] ?: emptyList()
|
|
||||||
|
|
||||||
ContentCard(
|
ImagesCard(id = personId, appNavController = appNavController)
|
||||||
title = stringResource(R.string.known_for_label)
|
|
||||||
) {
|
|
||||||
LazyRow(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.wrapContentHeight()
|
|
||||||
.padding(12.dp),
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
|
||||||
) {
|
|
||||||
items(min(credits.size, 15)) { i ->
|
|
||||||
val content = credits[i]
|
|
||||||
|
|
||||||
TwoLineImageTextCard(
|
|
||||||
title = content.title,
|
|
||||||
titleTextColor = MaterialTheme.colorScheme.primary,
|
|
||||||
subtitle = content.character,
|
|
||||||
modifier = Modifier
|
|
||||||
.width(124.dp)
|
|
||||||
.wrapContentHeight(),
|
|
||||||
imageUrl = TmdbUtils.getFullPosterPath(content.posterPath),
|
|
||||||
onItemClicked = {
|
|
||||||
appNavController.navigate(
|
|
||||||
AppNavItem.DetailView.withArgs(content.mediaType, content.id)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = stringResource(id = R.string.expand_see_all),
|
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
||||||
fontSize = 12.sp,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(start = 16.dp, bottom = 16.dp)
|
|
||||||
.clickable {
|
|
||||||
appNavController.navigate(AppNavItem.KnownForView.withArgs(personId))
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,3 +153,110 @@ private fun BiographyCard(person: DetailPerson?) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun CreditsCard(
|
||||||
|
personId: Int,
|
||||||
|
appNavController: NavController
|
||||||
|
) {
|
||||||
|
val mainViewModel = viewModel<MainViewModel>()
|
||||||
|
|
||||||
|
val creditsMap = remember { mainViewModel.peopleCastMap }
|
||||||
|
val credits = creditsMap[personId] ?: emptyList()
|
||||||
|
|
||||||
|
ContentCard(
|
||||||
|
title = stringResource(R.string.known_for_label)
|
||||||
|
) {
|
||||||
|
LazyRow(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.padding(vertical = 12.dp),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
}
|
||||||
|
items(min(credits.size, 15)) { i ->
|
||||||
|
val content = credits[i]
|
||||||
|
|
||||||
|
TwoLineImageTextCard(
|
||||||
|
title = content.title,
|
||||||
|
titleTextColor = MaterialTheme.colorScheme.primary,
|
||||||
|
subtitle = content.character,
|
||||||
|
modifier = Modifier
|
||||||
|
.width(124.dp)
|
||||||
|
.wrapContentHeight(),
|
||||||
|
imageUrl = TmdbUtils.getFullPosterPath(content.posterPath),
|
||||||
|
onItemClicked = {
|
||||||
|
appNavController.navigate(
|
||||||
|
AppNavItem.DetailView.withArgs(content.mediaType, content.id)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = R.string.expand_see_all),
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 16.dp, bottom = 16.dp)
|
||||||
|
.clickable {
|
||||||
|
appNavController.navigate(AppNavItem.KnownForView.withArgs(personId))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ImagesCard(
|
||||||
|
id: Int,
|
||||||
|
appNavController: NavController
|
||||||
|
) {
|
||||||
|
val mainViewModel = viewModel<MainViewModel>()
|
||||||
|
val imagesMap = remember { mainViewModel.peopleImagesMap }
|
||||||
|
val images = imagesMap[id] ?: emptyList()
|
||||||
|
|
||||||
|
ContentCard(
|
||||||
|
title = stringResource(R.string.images_title)
|
||||||
|
) {
|
||||||
|
LazyRow(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.padding(vertical = 12.dp),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
}
|
||||||
|
items(images) { image ->
|
||||||
|
PosterItem(
|
||||||
|
width = 120.dp,
|
||||||
|
url = TmdbUtils.getFullPersonImagePath(image.filePath),
|
||||||
|
placeholder = Icons.Filled.Person,
|
||||||
|
title = ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = R.string.expand_see_all),
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 16.dp, bottom = 16.dp)
|
||||||
|
.clickable {
|
||||||
|
appNavController.navigate(AppNavItem.GalleryView.withArgs(MediaViewType.PERSON, id))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -237,4 +237,5 @@
|
|||||||
<string name="cast_character_template">as %1$s</string>
|
<string name="cast_character_template">as %1$s</string>
|
||||||
<string name="cast_tv_character_template">as %1$s (%2$d eps.)</string>
|
<string name="cast_tv_character_template">as %1$s (%2$d eps.)</string>
|
||||||
<string name="crew_template">… %1$s</string>
|
<string name="crew_template">… %1$s</string>
|
||||||
|
<string name="images_title">Images</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user