mirror of
https://github.com/bbara04/Purefin.git
synced 2026-04-01 01:30:08 +02:00
refactor: Extract and generalize MediaHero component. Now MovieScreen, SeriesScreen and EpisodeScreen also use the same Component.
This commit is contained in:
@@ -27,9 +27,9 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.Dp
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
@@ -38,9 +38,9 @@ import hu.bbara.purefin.common.ui.MediaCastMember
|
|||||||
import hu.bbara.purefin.common.ui.MediaCastRow
|
import hu.bbara.purefin.common.ui.MediaCastRow
|
||||||
import hu.bbara.purefin.common.ui.MediaFloatingPlayButton
|
import hu.bbara.purefin.common.ui.MediaFloatingPlayButton
|
||||||
import hu.bbara.purefin.common.ui.MediaGhostIconButton
|
import hu.bbara.purefin.common.ui.MediaGhostIconButton
|
||||||
import hu.bbara.purefin.common.ui.MediaHero
|
|
||||||
import hu.bbara.purefin.common.ui.MediaMetaChip
|
import hu.bbara.purefin.common.ui.MediaMetaChip
|
||||||
import hu.bbara.purefin.common.ui.MediaPlaybackSettings
|
import hu.bbara.purefin.common.ui.MediaPlaybackSettings
|
||||||
|
import hu.bbara.purefin.common.ui.components.MediaHero
|
||||||
import hu.bbara.purefin.common.ui.toMediaDetailColors
|
import hu.bbara.purefin.common.ui.toMediaDetailColors
|
||||||
import hu.bbara.purefin.player.PlayerActivity
|
import hu.bbara.purefin.player.PlayerActivity
|
||||||
|
|
||||||
@@ -68,27 +68,6 @@ internal fun EpisodeTopBar(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun EpisodeHero(
|
|
||||||
episode: EpisodeUiModel,
|
|
||||||
height: Dp,
|
|
||||||
isWide: Boolean,
|
|
||||||
onPlayClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier
|
|
||||||
) {
|
|
||||||
val colors = rememberEpisodeColors().toMediaDetailColors()
|
|
||||||
MediaHero(
|
|
||||||
imageUrl = episode.heroImageUrl,
|
|
||||||
colors = colors,
|
|
||||||
height = height,
|
|
||||||
isWide = isWide,
|
|
||||||
modifier = modifier,
|
|
||||||
showPlayButton = true,
|
|
||||||
playButtonSize = if (isWide) 96.dp else 80.dp,
|
|
||||||
onPlayClick = onPlayClick
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalLayoutApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
internal fun EpisodeDetails(
|
internal fun EpisodeDetails(
|
||||||
@@ -164,6 +143,7 @@ internal fun EpisodeDetails(
|
|||||||
@Composable
|
@Composable
|
||||||
fun EpisodeCard(
|
fun EpisodeCard(
|
||||||
episode: EpisodeUiModel,
|
episode: EpisodeUiModel,
|
||||||
|
backGroundColor: Color,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val colors = rememberEpisodeColors().toMediaDetailColors()
|
val colors = rememberEpisodeColors().toMediaDetailColors()
|
||||||
@@ -187,11 +167,10 @@ fun EpisodeCard(
|
|||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
if (isWide) {
|
if (isWide) {
|
||||||
Row(modifier = Modifier.fillMaxSize()) {
|
Row(modifier = Modifier.fillMaxSize()) {
|
||||||
EpisodeHero(
|
MediaHero(
|
||||||
episode = episode,
|
imageUrl = episode.heroImageUrl,
|
||||||
height = 300.dp,
|
height = 300.dp,
|
||||||
isWide = true,
|
backgroundColor = backGroundColor,
|
||||||
onPlayClick = playAction,
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.weight(0.5f)
|
.weight(0.5f)
|
||||||
@@ -216,11 +195,10 @@ fun EpisodeCard(
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
) {
|
) {
|
||||||
EpisodeHero(
|
MediaHero(
|
||||||
episode = episode,
|
imageUrl = episode.heroImageUrl,
|
||||||
|
backgroundColor = backGroundColor,
|
||||||
height = 400.dp,
|
height = 400.dp,
|
||||||
isWide = false,
|
|
||||||
onPlayClick = playAction,
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
EpisodeDetails(
|
EpisodeDetails(
|
||||||
@@ -242,7 +220,8 @@ fun EpisodeCard(
|
|||||||
|
|
||||||
if (!isWide) {
|
if (!isWide) {
|
||||||
MediaFloatingPlayButton(
|
MediaFloatingPlayButton(
|
||||||
colors = colors,
|
containerColor = colors.primary,
|
||||||
|
onContainerColor = colors.onPrimary,
|
||||||
onClick = playAction,
|
onClick = playAction,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.BottomEnd)
|
.align(Alignment.BottomEnd)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package hu.bbara.purefin.app.content.episode
|
package hu.bbara.purefin.app.content.episode
|
||||||
|
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
@@ -24,7 +25,8 @@ fun EpisodeScreen(
|
|||||||
if (episode.value != null) {
|
if (episode.value != null) {
|
||||||
EpisodeCard(
|
EpisodeCard(
|
||||||
episode = episode.value!!,
|
episode = episode.value!!,
|
||||||
modifier = modifier
|
modifier = modifier,
|
||||||
|
backGroundColor = MaterialTheme.colorScheme.background
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
PurefinWaitingScreen()
|
PurefinWaitingScreen()
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.outlined.ArrowBack
|
import androidx.compose.material.icons.outlined.ArrowBack
|
||||||
import androidx.compose.material.icons.outlined.Cast
|
import androidx.compose.material.icons.outlined.Cast
|
||||||
import androidx.compose.material.icons.outlined.MoreVert
|
import androidx.compose.material.icons.outlined.MoreVert
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@@ -29,7 +30,6 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.Dp
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
@@ -38,9 +38,9 @@ import hu.bbara.purefin.common.ui.MediaCastMember
|
|||||||
import hu.bbara.purefin.common.ui.MediaCastRow
|
import hu.bbara.purefin.common.ui.MediaCastRow
|
||||||
import hu.bbara.purefin.common.ui.MediaFloatingPlayButton
|
import hu.bbara.purefin.common.ui.MediaFloatingPlayButton
|
||||||
import hu.bbara.purefin.common.ui.MediaGhostIconButton
|
import hu.bbara.purefin.common.ui.MediaGhostIconButton
|
||||||
import hu.bbara.purefin.common.ui.MediaHero
|
|
||||||
import hu.bbara.purefin.common.ui.MediaMetaChip
|
import hu.bbara.purefin.common.ui.MediaMetaChip
|
||||||
import hu.bbara.purefin.common.ui.MediaPlaybackSettings
|
import hu.bbara.purefin.common.ui.MediaPlaybackSettings
|
||||||
|
import hu.bbara.purefin.common.ui.components.MediaHero
|
||||||
import hu.bbara.purefin.common.ui.toMediaDetailColors
|
import hu.bbara.purefin.common.ui.toMediaDetailColors
|
||||||
import hu.bbara.purefin.player.PlayerActivity
|
import hu.bbara.purefin.player.PlayerActivity
|
||||||
|
|
||||||
@@ -68,27 +68,6 @@ internal fun MovieTopBar(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun MovieHero(
|
|
||||||
movie: MovieUiModel,
|
|
||||||
height: Dp,
|
|
||||||
isWide: Boolean,
|
|
||||||
onPlayClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier
|
|
||||||
) {
|
|
||||||
val colors = rememberMovieColors().toMediaDetailColors()
|
|
||||||
MediaHero(
|
|
||||||
imageUrl = movie.heroImageUrl,
|
|
||||||
colors = colors,
|
|
||||||
height = height,
|
|
||||||
isWide = isWide,
|
|
||||||
modifier = modifier,
|
|
||||||
showPlayButton = true,
|
|
||||||
playButtonSize = if (isWide) 96.dp else 80.dp,
|
|
||||||
onPlayClick = onPlayClick
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalLayoutApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
internal fun MovieDetails(
|
internal fun MovieDetails(
|
||||||
@@ -161,12 +140,13 @@ internal fun MovieDetails(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MovieCard(
|
fun MovieCard(
|
||||||
movie: MovieUiModel,
|
movie: MovieUiModel,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val colors = rememberMovieColors().toMediaDetailColors()
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val playAction = remember(movie.id) {
|
val playAction = remember(movie.id) {
|
||||||
{
|
{
|
||||||
@@ -179,7 +159,7 @@ fun MovieCard(
|
|||||||
BoxWithConstraints(
|
BoxWithConstraints(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(colors.background)
|
.background(MaterialTheme.colorScheme.background)
|
||||||
) {
|
) {
|
||||||
val isWide = maxWidth >= 900.dp
|
val isWide = maxWidth >= 900.dp
|
||||||
val contentPadding = if (isWide) 32.dp else 20.dp
|
val contentPadding = if (isWide) 32.dp else 20.dp
|
||||||
@@ -187,11 +167,10 @@ fun MovieCard(
|
|||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
if (isWide) {
|
if (isWide) {
|
||||||
Row(modifier = Modifier.fillMaxSize()) {
|
Row(modifier = Modifier.fillMaxSize()) {
|
||||||
MovieHero(
|
MediaHero(
|
||||||
movie = movie,
|
imageUrl = movie.heroImageUrl,
|
||||||
|
backgroundColor = MaterialTheme.colorScheme.background,
|
||||||
height = 300.dp,
|
height = 300.dp,
|
||||||
isWide = true,
|
|
||||||
onPlayClick = playAction,
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.weight(0.5f)
|
.weight(0.5f)
|
||||||
@@ -216,11 +195,10 @@ fun MovieCard(
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
) {
|
) {
|
||||||
MovieHero(
|
MediaHero(
|
||||||
movie = movie,
|
imageUrl = movie.heroImageUrl,
|
||||||
height = 400.dp,
|
height = 400.dp,
|
||||||
isWide = false,
|
backgroundColor = MaterialTheme.colorScheme.background,
|
||||||
onPlayClick = playAction,
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
MovieDetails(
|
MovieDetails(
|
||||||
@@ -242,7 +220,9 @@ fun MovieCard(
|
|||||||
|
|
||||||
if (!isWide) {
|
if (!isWide) {
|
||||||
MediaFloatingPlayButton(
|
MediaFloatingPlayButton(
|
||||||
colors = colors,
|
containerColor = MaterialTheme.colorScheme.primary,
|
||||||
|
onContainerColor = MaterialTheme.colorScheme.onPrimary,
|
||||||
|
|
||||||
onClick = playAction,
|
onClick = playAction,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.BottomEnd)
|
.align(Alignment.BottomEnd)
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import androidx.compose.material.icons.outlined.Cast
|
|||||||
import androidx.compose.material.icons.outlined.MoreVert
|
import androidx.compose.material.icons.outlined.MoreVert
|
||||||
import androidx.compose.material.icons.outlined.PlayCircle
|
import androidx.compose.material.icons.outlined.PlayCircle
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
@@ -47,8 +48,8 @@ import hu.bbara.purefin.common.ui.MediaActionButtons
|
|||||||
import hu.bbara.purefin.common.ui.MediaCastMember
|
import hu.bbara.purefin.common.ui.MediaCastMember
|
||||||
import hu.bbara.purefin.common.ui.MediaCastRow
|
import hu.bbara.purefin.common.ui.MediaCastRow
|
||||||
import hu.bbara.purefin.common.ui.MediaGhostIconButton
|
import hu.bbara.purefin.common.ui.MediaGhostIconButton
|
||||||
import hu.bbara.purefin.common.ui.MediaHero
|
|
||||||
import hu.bbara.purefin.common.ui.MediaMetaChip
|
import hu.bbara.purefin.common.ui.MediaMetaChip
|
||||||
|
import hu.bbara.purefin.common.ui.components.MediaHero
|
||||||
import hu.bbara.purefin.common.ui.toMediaDetailColors
|
import hu.bbara.purefin.common.ui.toMediaDetailColors
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -83,12 +84,9 @@ internal fun SeriesHero(
|
|||||||
val colors = rememberSeriesColors().toMediaDetailColors()
|
val colors = rememberSeriesColors().toMediaDetailColors()
|
||||||
MediaHero(
|
MediaHero(
|
||||||
imageUrl = imageUrl,
|
imageUrl = imageUrl,
|
||||||
colors = colors,
|
backgroundColor = MaterialTheme.colorScheme.background,
|
||||||
height = height,
|
height = height,
|
||||||
isWide = false,
|
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
showPlayButton = false,
|
|
||||||
horizontalGradientOnWide = false
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.draw.shadow
|
import androidx.compose.ui.draw.shadow
|
||||||
import androidx.compose.ui.graphics.Brush
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
@@ -128,71 +127,6 @@ fun MediaGhostIconButton(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun MediaHero(
|
|
||||||
imageUrl: String,
|
|
||||||
colors: MediaDetailColors,
|
|
||||||
height: Dp,
|
|
||||||
isWide: Boolean,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
showPlayButton: Boolean = false,
|
|
||||||
playButtonSize: Dp = 80.dp,
|
|
||||||
onPlayClick: (() -> Unit)? = null,
|
|
||||||
horizontalGradientOnWide: Boolean = true
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = modifier
|
|
||||||
.height(height)
|
|
||||||
.background(colors.background)
|
|
||||||
) {
|
|
||||||
AsyncImage(
|
|
||||||
model = imageUrl,
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
contentScale = ContentScale.Crop
|
|
||||||
)
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.matchParentSize()
|
|
||||||
.background(
|
|
||||||
Brush.verticalGradient(
|
|
||||||
colors = listOf(
|
|
||||||
Color.Transparent,
|
|
||||||
colors.background.copy(alpha = 0.4f),
|
|
||||||
colors.background
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if (horizontalGradientOnWide && isWide) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.matchParentSize()
|
|
||||||
.background(
|
|
||||||
Brush.horizontalGradient(
|
|
||||||
colors = listOf(
|
|
||||||
Color.Transparent,
|
|
||||||
colors.background.copy(alpha = 0.8f)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (showPlayButton && onPlayClick != null) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
MediaPlayButton(
|
|
||||||
colors = colors,
|
|
||||||
size = playButtonSize,
|
|
||||||
onClick = onPlayClick
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MediaMetaChip(
|
fun MediaMetaChip(
|
||||||
colors: MediaDetailColors,
|
colors: MediaDetailColors,
|
||||||
@@ -469,7 +403,8 @@ fun MediaPlayButton(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MediaFloatingPlayButton(
|
fun MediaFloatingPlayButton(
|
||||||
colors: MediaDetailColors,
|
containerColor: Color,
|
||||||
|
onContainerColor: Color,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
@@ -478,14 +413,14 @@ fun MediaFloatingPlayButton(
|
|||||||
.size(56.dp)
|
.size(56.dp)
|
||||||
.shadow(20.dp, CircleShape)
|
.shadow(20.dp, CircleShape)
|
||||||
.clip(CircleShape)
|
.clip(CircleShape)
|
||||||
.background(colors.primary)
|
.background(containerColor)
|
||||||
.clickable { onClick() },
|
.clickable { onClick() },
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.PlayArrow,
|
imageVector = Icons.Filled.PlayArrow,
|
||||||
contentDescription = "Play",
|
contentDescription = "Play",
|
||||||
tint = colors.onPrimary
|
tint = onContainerColor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package hu.bbara.purefin.common.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import coil3.compose.AsyncImage
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MediaHero(
|
||||||
|
imageUrl: String,
|
||||||
|
backgroundColor: Color,
|
||||||
|
height: Dp,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.height(height)
|
||||||
|
.background(backgroundColor)
|
||||||
|
) {
|
||||||
|
AsyncImage(
|
||||||
|
model = imageUrl,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentScale = ContentScale.Crop
|
||||||
|
)
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.matchParentSize()
|
||||||
|
.background(
|
||||||
|
Brush.verticalGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color.Transparent,
|
||||||
|
backgroundColor.copy(alpha = 0.4f),
|
||||||
|
backgroundColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.matchParentSize()
|
||||||
|
.background(
|
||||||
|
Brush.horizontalGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color.Transparent,
|
||||||
|
backgroundColor.copy(alpha = 0.8f)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user