Skip to content

Commit

Permalink
Display chapter in the demo tv
Browse files Browse the repository at this point in the history
  • Loading branch information
StaehliJ committed Apr 19, 2024
1 parent 5d96917 commit 1021024
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
package ch.srgssr.pillarbox.demo.tv.ui.player.compose

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.media3.common.MediaMetadata
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text
import ch.srgssr.pillarbox.demo.tv.ui.theme.paddings
import coil.compose.AsyncImage

/**
* Media metadata view
*
* @param mediaMetadata The [MediaMetadata] to display.
* @param modifier The Modifier.
*/
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
fun MediaMetadataView(
mediaMetadata: MediaMetadata,
modifier: Modifier = Modifier,
) {
Row(modifier.background(color = Color.Black)) {
AsyncImage(
modifier = Modifier
.width(200.dp)
.aspectRatio(16 / 9f),
contentScale = ContentScale.Fit,
model = mediaMetadata.artworkUri,
contentDescription = null,
)
Column(
verticalArrangement = Arrangement.Bottom,
modifier = Modifier.padding(MaterialTheme.paddings.mini)
) {
Text(
text = mediaMetadata.title?.toString() ?: "No title",
color = Color.White,
style = MaterialTheme.typography.bodyLarge,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
mediaMetadata.description?.let {
Text(
text = mediaMetadata.description.toString(),
color = Color.White,
style = MaterialTheme.typography.bodyMedium,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
)
}
}
}
}

@Preview(device = Devices.TV_1080p)
@Composable
private fun MediaMetadataPreview() {
val mediaMetadata = MediaMetadata.Builder().setTitle("Title").setDescription("Description").build()
MediaMetadataView(mediaMetadata = mediaMetadata, modifier = Modifier.fillMaxSize())
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Settings
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
Expand All @@ -33,10 +39,16 @@ import ch.srgssr.pillarbox.demo.tv.ui.player.compose.controls.PlayerError
import ch.srgssr.pillarbox.demo.tv.ui.player.compose.controls.PlayerPlaybackRow
import ch.srgssr.pillarbox.demo.tv.ui.player.compose.settings.PlaybackSettingsDrawer
import ch.srgssr.pillarbox.demo.tv.ui.theme.paddings
import ch.srgssr.pillarbox.player.extension.getChapterAtPosition
import ch.srgssr.pillarbox.player.getCurrentChapterAsFlow
import ch.srgssr.pillarbox.ui.extension.currentMediaMetadataAsState
import ch.srgssr.pillarbox.ui.extension.playerErrorAsState
import ch.srgssr.pillarbox.ui.widget.maintainVisibleOnFocus
import ch.srgssr.pillarbox.ui.widget.player.PlayerSurface
import ch.srgssr.pillarbox.ui.widget.rememberDelayedVisibilityState
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.map
import kotlin.time.Duration.Companion.seconds

/**
* Tv player view
Expand Down Expand Up @@ -69,6 +81,10 @@ fun PlayerView(
if (error != null) {
PlayerError(modifier = Modifier.fillMaxSize(), playerError = error!!, onRetry = player::prepare)
} else {
val chapterFlow = remember(player) {
player.getCurrentChapterAsFlow().map { it?.mediaMetadata }
}
val chapterMetaData by chapterFlow.collectAsState(initial = player.getChapterAtPosition()?.mediaMetadata)
PlayerSurface(
player = player,
modifier = Modifier
Expand All @@ -81,6 +97,33 @@ fun PlayerView(
)
.focusable(true)
)
var chapterInfoVisibility by remember {
mutableStateOf(chapterMetaData != null)
}
LaunchedEffect(chapterMetaData) {
chapterInfoVisibility = chapterMetaData != null
if (chapterInfoVisibility) {
delay(5.seconds)
chapterInfoVisibility = false
}
}
AnimatedVisibility(
visible = !visibilityState.isVisible && chapterInfoVisibility,
enter = expandVertically { it },
exit = shrinkVertically { it }
) {
Box(modifier = Modifier.fillMaxSize()) {
chapterMetaData?.let {
MediaMetadataView(
modifier = Modifier
.fillMaxWidth(0.5f)
.wrapContentHeight()
.align(Alignment.BottomStart),
mediaMetadata = it
)
}
}
}
AnimatedVisibility(
visible = visibilityState.isVisible,
enter = expandVertically { it },
Expand All @@ -97,6 +140,15 @@ fun PlayerView(
state = visibilityState
)

val currentMediaMetadata by player.currentMediaMetadataAsState()
MediaMetadataView(
modifier = Modifier
.fillMaxWidth(0.5f)
.wrapContentHeight()
.align(Alignment.BottomStart),
mediaMetadata = chapterMetaData ?: currentMediaMetadata
)

IconButton(
onClick = { drawerState.setValue(DrawerValue.Open) },
modifier = Modifier
Expand Down

0 comments on commit 1021024

Please sign in to comment.