mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-18 09:40:53 -05:00
more details view refactoring
This commit is contained in:
@@ -63,6 +63,7 @@ dependencies {
|
||||
implementation "androidx.activity:activity-compose:${Versions.activity_compose}"
|
||||
implementation "com.google.accompanist:accompanist-systemuicontroller:${Versions.compose_accompanist}"
|
||||
implementation "com.google.accompanist:accompanist-pager:${Versions.compose_accompanist}"
|
||||
implementation "com.google.accompanist:accompanist-pager-indicators:${Versions.compose_accompanist}"
|
||||
implementation "com.google.accompanist:accompanist-flowlayout:${Versions.compose_accompanist}"
|
||||
// implementation "com.google.accompanist:accompanist-insets:${Versions.compose_accompanist}"
|
||||
implementation "androidx.navigation:navigation-compose:${Versions.compose_navigation}"
|
||||
|
||||
@@ -77,7 +77,7 @@ fun DetailHeader(
|
||||
modifier = Modifier
|
||||
.constrainAs(posterImage) {
|
||||
bottom.linkTo(backdropImage.bottom)
|
||||
start.linkTo(parent.start)
|
||||
start.linkTo(parent.start, margin = 16.dp)
|
||||
top.linkTo(backButton.bottom)
|
||||
},
|
||||
url = posterUrl,
|
||||
@@ -89,7 +89,7 @@ fun DetailHeader(
|
||||
.constrainAs(titleText) {
|
||||
bottom.linkTo(posterImage.bottom)
|
||||
start.linkTo(posterImage.end, margin = 8.dp)
|
||||
end.linkTo(parent.end)
|
||||
end.linkTo(parent.end, margin = 16.dp)
|
||||
},
|
||||
title = title
|
||||
)
|
||||
@@ -108,7 +108,7 @@ fun DetailHeader(
|
||||
BackButton(
|
||||
modifier = Modifier.constrainAs(backButton) {
|
||||
top.linkTo(parent.top)//, 8.dp)
|
||||
start.linkTo(parent.start)//, 12.dp)
|
||||
start.linkTo(parent.start, 8.dp)
|
||||
bottom.linkTo(posterImage.top)
|
||||
},
|
||||
appNavController = appNavController
|
||||
|
||||
@@ -2,9 +2,12 @@ package com.owenlejeune.tvtime.ui.screens
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Send
|
||||
@@ -58,33 +61,34 @@ fun MediaDetailView(
|
||||
}
|
||||
}
|
||||
|
||||
DetailContent(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(color = MaterialTheme.colorScheme.background)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.fillMaxSize()
|
||||
.padding(bottom = 16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
DetailHeader(
|
||||
appNavController = appNavController,
|
||||
title = mediaItem.value?.title ?: "",
|
||||
posterUrl = TmdbUtils.getFullPosterPath(mediaItem.value?.posterPath),
|
||||
posterContentDescription = mediaItem.value?.title,
|
||||
backdropUrl = TmdbUtils.getFullBackdropPath(mediaItem.value?.backdropPath),
|
||||
rating = mediaItem.value?.voteAverage?.let { it / 10 }
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp),
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
DetailHeader(
|
||||
appNavController = appNavController,
|
||||
title = mediaItem.value?.title ?: "",
|
||||
posterUrl = TmdbUtils.getFullPosterPath(mediaItem.value?.posterPath),
|
||||
posterContentDescription = mediaItem.value?.title,
|
||||
backdropUrl = TmdbUtils.getFullBackdropPath(mediaItem.value?.backdropPath),
|
||||
rating = mediaItem.value?.voteAverage?.let { it / 10 }
|
||||
)
|
||||
|
||||
if (type == MediaViewType.MOVIE) {
|
||||
MiscMovieDetails(mediaItem = mediaItem, service as MoviesService)
|
||||
} else {
|
||||
MiscTvDetails(mediaItem = mediaItem, service as TvService)
|
||||
}
|
||||
|
||||
if (itemId != null && mediaItem.value != null) {
|
||||
OverviewCard(itemId = itemId, mediaItem.value!!, service)
|
||||
}
|
||||
OverviewCard(itemId = itemId, mediaItem = mediaItem, service = service)
|
||||
|
||||
CastCard(itemId = itemId, service = service, appNavController = appNavController)
|
||||
|
||||
@@ -96,7 +100,8 @@ fun MediaDetailView(
|
||||
|
||||
ReviewsCard(itemId = itemId, service = service)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -335,14 +340,15 @@ private fun RatingDialog(showDialog: MutableState<Boolean>, onValueConfirmed: (F
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun OverviewCard(itemId: Int, mediaItem: DetailedItem, service: DetailService, modifier: Modifier = Modifier) {
|
||||
private fun OverviewCard(itemId: Int?, mediaItem: MutableState<DetailedItem?>, service: DetailService, modifier: Modifier = Modifier) {
|
||||
val keywordResponse = remember { mutableStateOf<KeywordsResponse?>(null) }
|
||||
if (keywordResponse.value == null) {
|
||||
fetchKeywords(itemId, service, keywordResponse)
|
||||
if (itemId != null) {
|
||||
if (keywordResponse.value == null) {
|
||||
fetchKeywords(itemId, service, keywordResponse)
|
||||
}
|
||||
}
|
||||
val context = LocalContext.current
|
||||
|
||||
mediaItem.overview?.let { overview ->
|
||||
mediaItem.value?.let { mi ->
|
||||
ContentCard(
|
||||
modifier = modifier
|
||||
) {
|
||||
@@ -353,7 +359,7 @@ private fun OverviewCard(itemId: Int, mediaItem: DetailedItem, service: DetailSe
|
||||
.padding(vertical = 12.dp, horizontal = 16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
mediaItem.tagline?.let { tagline ->
|
||||
mi.tagline?.let { tagline ->
|
||||
Text(
|
||||
text = tagline,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
@@ -362,7 +368,7 @@ private fun OverviewCard(itemId: Int, mediaItem: DetailedItem, service: DetailSe
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = overview,
|
||||
text = mi.overview ?: "",
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.owenlejeune.tvtime.ui.screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -39,21 +42,25 @@ fun PersonDetailView(
|
||||
}
|
||||
}
|
||||
|
||||
DetailContent(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(color = MaterialTheme.colorScheme.background)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.fillMaxSize()
|
||||
.padding(bottom = 16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
DetailHeader(
|
||||
appNavController = appNavController,
|
||||
title = person.value?.name ?: "",
|
||||
posterUrl = TmdbUtils.getFullPersonImagePath(person.value?.profilePath),
|
||||
posterContentDescription = person.value?.name
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp),
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
DetailHeader(
|
||||
appNavController = appNavController,
|
||||
title = person.value?.name ?: "",
|
||||
posterUrl = TmdbUtils.getFullPersonImagePath(person.value?.profilePath),
|
||||
posterContentDescription = person.value?.name
|
||||
)
|
||||
|
||||
BiographyCard(person = person.value)
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ fun AccountTabContent(
|
||||
) {
|
||||
val contentItems = listFetchFun()
|
||||
|
||||
if (contentItems.isNotEmpty() && contentItems[0] is RatedTopLevelMedia) {
|
||||
LazyColumn(modifier = Modifier.fillMaxWidth().padding(12.dp)) {
|
||||
// if (contentItems.isNotEmpty() && contentItems[0] is RatedTopLevelMedia) {
|
||||
LazyColumn(modifier = Modifier.fillMaxSize().padding(12.dp)) {
|
||||
items(contentItems.size) { i ->
|
||||
val ratedItem = contentItems[i] as RatedTopLevelMedia
|
||||
|
||||
@@ -112,7 +112,7 @@ fun AccountTabContent(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ fun MediaTab(appNavController: NavHostController, mediaType: MediaViewType) {
|
||||
else -> throw IllegalArgumentException("Media type given: ${mediaType}, \n expected one of MediaViewType.MOVIE, MediaViewType.TV") // shouldn't happen
|
||||
}
|
||||
val pagerState = rememberPagerState()
|
||||
ScrollableTabs(tabs = tabs, pagerState = pagerState)
|
||||
Tabs(tabs = tabs, pagerState = pagerState)
|
||||
MediaTabs(
|
||||
tabs = tabs,
|
||||
pagerState = pagerState,
|
||||
|
||||
@@ -2,13 +2,13 @@ package com.owenlejeune.tvtime.ui.screens.tabs.top
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.ScrollableTabRow
|
||||
import androidx.compose.material.Tab
|
||||
import androidx.compose.material.TabRow
|
||||
import androidx.compose.material.TabRowDefaults.tabIndicatorOffset
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -16,10 +16,12 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||
import com.google.accompanist.pager.PagerState
|
||||
import com.google.accompanist.pager.pagerTabIndicatorOffset
|
||||
import com.google.accompanist.pager.rememberPagerState
|
||||
import com.owenlejeune.tvtime.ui.navigation.MediaTabNavItem
|
||||
import com.owenlejeune.tvtime.ui.navigation.TabNavItem
|
||||
@@ -47,7 +49,7 @@ fun Tabs(
|
||||
contentColor = contentColor,
|
||||
indicator = { tabPositions ->
|
||||
SmallTabIndicator(
|
||||
modifier = Modifier.tabIndicatorOffset(tabPositions[pagerState.currentPage]),
|
||||
modifier = Modifier.pagerTabIndicatorOffset(pagerState = pagerState, tabPositions = tabPositions),
|
||||
color = tabIndicatorColor
|
||||
)
|
||||
}
|
||||
@@ -58,7 +60,8 @@ fun Tabs(
|
||||
Text(
|
||||
text = tab.name,
|
||||
style = tabTextStyle,
|
||||
color = if (pagerState.currentPage == index) selectedTabTextColor else unselectedTabTextColor
|
||||
color = if (pagerState.currentPage == index) selectedTabTextColor else unselectedTabTextColor,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
},
|
||||
selected = pagerState.currentPage == index,
|
||||
@@ -88,14 +91,15 @@ fun ScrollableTabs(
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
ScrollableTabRow(
|
||||
modifier = modifier,
|
||||
modifier = modifier
|
||||
.fillMaxWidth(),
|
||||
selectedTabIndex = pagerState.currentPage,
|
||||
backgroundColor = backgroundColor,
|
||||
contentColor = contentColor,
|
||||
edgePadding = 8.dp,
|
||||
indicator = { tabPositions ->
|
||||
SmallTabIndicator(
|
||||
modifier = Modifier.tabIndicatorOffset(tabPositions[pagerState.currentPage]),
|
||||
modifier = Modifier.pagerTabIndicatorOffset(pagerState = pagerState, tabPositions = tabPositions),
|
||||
color = tabIndicatorColor
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user