mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-08 04:32:43 -05:00
add crew to movie/tv details
This commit is contained in:
@@ -20,6 +20,7 @@ import com.owenlejeune.tvtime.extensions.safeGetSerializable
|
||||
import com.owenlejeune.tvtime.preferences.AppPreferences
|
||||
import com.owenlejeune.tvtime.ui.screens.AboutScreen
|
||||
import com.owenlejeune.tvtime.ui.screens.AccountScreen
|
||||
import com.owenlejeune.tvtime.ui.screens.CastCrewListScreen
|
||||
import com.owenlejeune.tvtime.ui.screens.GalleryView
|
||||
import com.owenlejeune.tvtime.ui.screens.HomeScreen
|
||||
import com.owenlejeune.tvtime.ui.screens.KeywordResultsScreen
|
||||
@@ -211,6 +212,18 @@ fun AppNavigationHost(
|
||||
|
||||
SeasonListScreen(id = id, appNavController = appNavController)
|
||||
}
|
||||
composable(
|
||||
route = AppNavItem.CaseCrewListView.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)!!
|
||||
|
||||
CastCrewListScreen(appNavController = appNavController, type = type, id = id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,5 +260,8 @@ sealed class AppNavItem(val route: String) {
|
||||
object SeasonListView: AppNavItem("season_list_route") {
|
||||
fun withArgs(id: Int) = route.plus("/$id")
|
||||
}
|
||||
object CaseCrewListView: AppNavItem("cast_crew_list_route") {
|
||||
fun withArgs(type: MediaViewType, id: Int) = route.plus("/$type/$id")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
package com.owenlejeune.tvtime.ui.screens
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
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.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
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.api.tmdb.api.v3.model.CrewMember
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailCrew
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.MovieCast
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.MovieCastMember
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.TvCast
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.TvCastMember
|
||||
import com.owenlejeune.tvtime.extensions.getCalendarYear
|
||||
import com.owenlejeune.tvtime.ui.components.MediaResultCard
|
||||
import com.owenlejeune.tvtime.ui.components.SelectableTextChip
|
||||
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 CastCrewListScreen(
|
||||
appNavController: NavController,
|
||||
type: MediaViewType,
|
||||
id: Int
|
||||
) {
|
||||
val mainViewModel = viewModel<MainViewModel>()
|
||||
|
||||
val systemUiController = rememberSystemUiController()
|
||||
systemUiController.setStatusBarColor(color = MaterialTheme.colorScheme.background)
|
||||
systemUiController.setNavigationBarColor(color = MaterialTheme.colorScheme.background)
|
||||
|
||||
val topAppBarScrollState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(topAppBarScrollState)
|
||||
|
||||
val details = mainViewModel.produceDetailsFor(type)[id]
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
scrollBehavior = scrollBehavior,
|
||||
colors = TopAppBarDefaults
|
||||
.topAppBarColors(
|
||||
scrolledContainerColor = MaterialTheme.colorScheme.background,
|
||||
titleContentColor = MaterialTheme.colorScheme.primary
|
||||
),
|
||||
title = { Text(text = details?.title ?: "") },
|
||||
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)) {
|
||||
|
||||
val castMap = remember { mainViewModel.produceCastFor(type) }
|
||||
val crewMap = remember { mainViewModel.produceCrewFor(type) }
|
||||
|
||||
val cast = castMap[id]
|
||||
val crew = crewMap[id]
|
||||
|
||||
var castSelected by remember { mutableStateOf(true) }
|
||||
val items = if (castSelected) cast else crew
|
||||
|
||||
LazyColumn(
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
item {
|
||||
Row(
|
||||
modifier = Modifier.padding(start = 16.dp, top = 12.dp, bottom = 12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
SelectableTextChip(
|
||||
selected = castSelected,
|
||||
onSelected = { castSelected = true },
|
||||
text = stringResource(id = R.string.actor_label),
|
||||
selectedColor = MaterialTheme.colorScheme.tertiary,
|
||||
unselectedColor = MaterialTheme.colorScheme.background
|
||||
)
|
||||
SelectableTextChip(
|
||||
selected = !castSelected,
|
||||
onSelected = { castSelected = false },
|
||||
text = stringResource(id = R.string.production_label),
|
||||
selectedColor = MaterialTheme.colorScheme.tertiary,
|
||||
unselectedColor = MaterialTheme.colorScheme.background
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
items(items!!) { item ->
|
||||
val additionalDetails = emptyList<String>().toMutableList()
|
||||
when (item) {
|
||||
is MovieCastMember -> additionalDetails.add(stringResource(id = R.string.cast_character_template, item.character))
|
||||
is TvCastMember -> {
|
||||
item.roles.forEach { role ->
|
||||
additionalDetails.add(stringResource(id = R.string.cast_tv_character_template, role.role, role.episodeCount))
|
||||
}
|
||||
}
|
||||
is CrewMember -> additionalDetails.add(stringResource(id = R.string.crew_template, item.department))
|
||||
}
|
||||
|
||||
MediaResultCard(
|
||||
appNavController = appNavController,
|
||||
mediaViewType = type,
|
||||
id = item.id,
|
||||
backdropPath = null,
|
||||
posterPath = TmdbUtils.getFullPosterPath(item.profilePath),
|
||||
title = item.name,
|
||||
additionalDetails = additionalDetails,
|
||||
modifier = Modifier.padding(horizontal = 12.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -602,23 +602,36 @@ private fun CastCard(
|
||||
backgroundColor = MaterialTheme.colorScheme.primary,
|
||||
textColor = MaterialTheme.colorScheme.background
|
||||
) {
|
||||
LazyRow(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
item {
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
}
|
||||
items(cast?.size ?: 0) { i ->
|
||||
cast?.get(i)?.let {
|
||||
CastCrewCard(appNavController = appNavController, person = it)
|
||||
Column {
|
||||
LazyRow(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
item {
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
}
|
||||
items(cast?.size ?: 0) { i ->
|
||||
cast?.get(i)?.let {
|
||||
CastCrewCard(appNavController = appNavController, person = it)
|
||||
}
|
||||
}
|
||||
item {
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
}
|
||||
}
|
||||
item {
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
}
|
||||
|
||||
Text(
|
||||
text = "See all cast and crew",
|
||||
fontSize = 12.sp,
|
||||
color = MaterialTheme.colorScheme.inversePrimary,
|
||||
modifier = Modifier
|
||||
.padding(start = 12.dp, bottom = 12.dp)
|
||||
.clickable {
|
||||
appNavController.navigate(AppNavItem.CaseCrewListView.withArgs(type, itemId))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user