mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-12 06:42:45 -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.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.CastCrewListScreen
|
||||||
import com.owenlejeune.tvtime.ui.screens.GalleryView
|
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
|
||||||
@@ -211,6 +212,18 @@ fun AppNavigationHost(
|
|||||||
|
|
||||||
SeasonListScreen(id = id, appNavController = appNavController)
|
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") {
|
object SeasonListView: AppNavItem("season_list_route") {
|
||||||
fun withArgs(id: Int) = route.plus("/$id")
|
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,6 +602,7 @@ private fun CastCard(
|
|||||||
backgroundColor = MaterialTheme.colorScheme.primary,
|
backgroundColor = MaterialTheme.colorScheme.primary,
|
||||||
textColor = MaterialTheme.colorScheme.background
|
textColor = MaterialTheme.colorScheme.background
|
||||||
) {
|
) {
|
||||||
|
Column {
|
||||||
LazyRow(
|
LazyRow(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -620,6 +621,18 @@ private fun CastCard(
|
|||||||
Spacer(modifier = Modifier.width(8.dp))
|
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