Skip to content

Commit

Permalink
Switching to PodcastImage (#1360)
Browse files Browse the repository at this point in the history
This pull request switch the component to show thumbnails in tv apps
from `AsyncImage` into `PodcastImage`. As a side effect of the
migration, Podcast`, `PodcastWithExtraInfo` and `EpisodeToPodcast` are
replaced with their external models.
  • Loading branch information
chikoski authored Apr 25, 2024
2 parents 7631197 + 1793321 commit 359e278
Show file tree
Hide file tree
Showing 20 changed files with 190 additions and 182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
Expand All @@ -43,6 +43,7 @@ fun PodcastImage(
contentDescription: String?,
modifier: Modifier = Modifier,
contentScale: ContentScale = ContentScale.Crop,
placeholderBrush: Brush = thumbnailPlaceholderDefaultBrush(),
) {
var imagePainterState by remember {
mutableStateOf<AsyncImagePainter.State>(AsyncImagePainter.State.Empty)
Expand Down Expand Up @@ -73,8 +74,9 @@ fun PodcastImage(
else -> {
Box(
modifier = Modifier
.background(placeholderBrush)
.fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceContainerHigh)

)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,30 @@
* limitations under the License.
*/

package com.example.jetcaster.tv.ui.component
package com.example.jetcaster.designsystem.component

import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.painter.BrushPainter
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import com.example.jetcaster.designsystem.theme.surfaceVariantDark
import com.example.jetcaster.designsystem.theme.surfaceVariantLight

@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
internal fun thumbnailPlaceholder(
brush: Brush = SolidColor(MaterialTheme.colorScheme.surfaceVariant)
): BrushPainter {
return BrushPainter(brush)
internal fun thumbnailPlaceholderDefaultBrush(
color: Color = thumbnailPlaceHolderDefaultColor()
): Brush {
return SolidColor(color)
}

@Composable
private fun thumbnailPlaceHolderDefaultColor(
isInDarkMode: Boolean = isSystemInDarkTheme()
): Color {
return if (isInDarkMode) {
surfaceVariantDark
} else {
surfaceVariantLight
}
}
8 changes: 4 additions & 4 deletions Jetcaster/tv-app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ android {
buildTypes {
getByName("release") {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro")
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}

Expand Down Expand Up @@ -79,15 +81,13 @@ dependencies {
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.navigation.compose)
implementation(libs.coil.kt.compose)

// Dependency injection
implementation(libs.androidx.hilt.navigation.compose)
implementation(libs.hilt.android)
implementation(project(":core:model"))
ksp(libs.hilt.compiler)


implementation(project(":core"))
implementation(project(":designsystem"))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
package com.example.jetcaster.tv.model

import androidx.compose.runtime.Immutable
import com.example.jetcaster.core.data.database.model.PodcastWithExtraInfo
import com.example.jetcaster.core.model.PodcastInfo

@Immutable
data class PodcastList(
val member: List<PodcastWithExtraInfo>
) : List<PodcastWithExtraInfo> by member
val member: List<PodcastInfo>
) : List<PodcastInfo> by member
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ private fun Route(jetcasterAppState: JetcasterAppState) {
LibraryScreen(
navigateToDiscover = jetcasterAppState::navigateToDiscover,
showPodcastDetails = {
jetcasterAppState.showPodcastDetails(it.podcast.uri)
jetcasterAppState.showPodcastDetails(it.uri)
},
playEpisode = {
jetcasterAppState.playEpisode()
Expand All @@ -156,7 +156,7 @@ private fun Route(jetcasterAppState: JetcasterAppState) {
composable(Screen.Search.route) {
SearchScreen(
onPodcastSelected = {
jetcasterAppState.showPodcastDetails(it.podcast.uri)
jetcasterAppState.showPodcastDetails(it.uri)
},
modifier = Modifier
.padding(JetcasterAppDefaults.overScanMargin.default.intoPaddingValues())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,43 +23,54 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import com.example.jetcaster.core.data.database.model.Podcast
import com.example.jetcaster.core.model.PlayerEpisode
import com.example.jetcaster.core.model.PodcastInfo
import com.example.jetcaster.designsystem.component.ImageBackgroundRadialGradientScrim

@Composable
internal fun Background(
podcast: Podcast,
modifier: Modifier = Modifier,
) = Background(imageUrl = podcast.imageUrl, modifier)

@Composable
internal fun Background(
episode: PlayerEpisode,
internal fun BackgroundContainer(
playerEpisode: PlayerEpisode,
modifier: Modifier = Modifier,
) = Background(imageUrl = episode.podcastImageUrl, modifier)
contentAlignment: Alignment = Alignment.Center,
content: @Composable BoxScope.() -> Unit
) =
BackgroundContainer(
imageUrl = playerEpisode.podcastImageUrl,
modifier,
contentAlignment,
content
)

@Composable
internal fun Background(
imageUrl: String?,
internal fun BackgroundContainer(
podcastInfo: PodcastInfo,
modifier: Modifier = Modifier,
) {
ImageBackgroundRadialGradientScrim(
url = imageUrl,
colors = listOf(Color.Black, Color.Transparent),
modifier = modifier,
)
}
contentAlignment: Alignment = Alignment.Center,
content: @Composable BoxScope.() -> Unit
) =
BackgroundContainer(imageUrl = podcastInfo.imageUrl, modifier, contentAlignment, content)

@Composable
internal fun BackgroundContainer(
playerEpisode: PlayerEpisode,
imageUrl: String,
modifier: Modifier = Modifier,
contentAlignment: Alignment = Alignment.Center,
content: @Composable BoxScope.() -> Unit
) {
Box(modifier = modifier, contentAlignment = contentAlignment) {
Background(episode = playerEpisode, modifier = Modifier.fillMaxSize())
Background(imageUrl = imageUrl, modifier = Modifier.fillMaxSize())
content()
}
}

@Composable
private fun Background(
imageUrl: String,
modifier: Modifier = Modifier,
) {
ImageBackgroundRadialGradientScrim(
url = imageUrl,
colors = listOf(Color.Black, Color.Transparent),
modifier = modifier,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ import androidx.tv.foundation.lazy.list.rememberTvLazyListState
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text
import com.example.jetcaster.core.data.database.model.PodcastWithExtraInfo
import com.example.jetcaster.core.model.PlayerEpisode
import com.example.jetcaster.core.model.PodcastInfo
import com.example.jetcaster.tv.R
import com.example.jetcaster.tv.model.EpisodeList
import com.example.jetcaster.tv.model.PodcastList
Expand All @@ -46,7 +46,7 @@ import com.example.jetcaster.tv.ui.theme.JetcasterAppDefaults
internal fun Catalog(
podcastList: PodcastList,
latestEpisodeList: EpisodeList,
onPodcastSelected: (PodcastWithExtraInfo) -> Unit,
onPodcastSelected: (PodcastInfo) -> Unit,
onEpisodeSelected: (PlayerEpisode) -> Unit,
modifier: Modifier = Modifier,
state: TvLazyListState = rememberTvLazyListState(),
Expand Down Expand Up @@ -83,7 +83,7 @@ internal fun Catalog(
@Composable
private fun PodcastSection(
podcastList: PodcastList,
onPodcastSelected: (PodcastWithExtraInfo) -> Unit,
onPodcastSelected: (PodcastInfo) -> Unit,
modifier: Modifier = Modifier,
title: String? = null,
) {
Expand Down Expand Up @@ -142,7 +142,7 @@ private fun Section(
@Composable
private fun PodcastRow(
podcastList: PodcastList,
onPodcastSelected: (PodcastWithExtraInfo) -> Unit,
onPodcastSelected: (PodcastInfo) -> Unit,
modifier: Modifier = Modifier,
contentPadding: PaddingValues = PaddingValues(),
horizontalArrangement: Arrangement.Horizontal =
Expand All @@ -155,7 +155,7 @@ private fun PodcastRow(
) {
items(podcastList) {
PodcastCard(
podcast = it.podcast,
podcastInfo = it,
onClick = { onPodcastSelected(it) },
modifier = Modifier.width(JetcasterAppDefaults.cardWidth.medium)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package com.example.jetcaster.tv.ui.component
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
Expand All @@ -36,7 +35,6 @@ import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text
import androidx.tv.material3.WideCardLayout
import coil.compose.AsyncImage
import com.example.jetcaster.core.model.PlayerEpisode
import com.example.jetcaster.tv.ui.theme.JetcasterAppDefaults

Expand Down Expand Up @@ -78,12 +76,7 @@ private fun EpisodeThumbnail(
scale = CardScale.None,
modifier = modifier,
) {
AsyncImage(
model = playerEpisode.podcastImageUrl,
contentDescription = null,
placeholder = thumbnailPlaceholder(),
modifier = Modifier.fillMaxSize()
)
Thumbnail(episode = playerEpisode, size = JetcasterAppDefaults.thumbnailSize.episode)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package com.example.jetcaster.tv.ui.component

import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
Expand All @@ -26,14 +25,13 @@ import androidx.tv.material3.CardScale
import androidx.tv.material3.ExperimentalTvMaterial3Api
import androidx.tv.material3.StandardCardLayout
import androidx.tv.material3.Text
import coil.compose.AsyncImage
import com.example.jetcaster.core.data.database.model.Podcast
import com.example.jetcaster.core.model.PodcastInfo
import com.example.jetcaster.tv.ui.theme.JetcasterAppDefaults

@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
internal fun PodcastCard(
podcast: Podcast,
podcastInfo: PodcastInfo,
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Expand All @@ -44,16 +42,14 @@ internal fun PodcastCard(
interactionSource = it,
scale = CardScale.None,
) {
AsyncImage(
model = podcast.imageUrl,
contentDescription = null,
placeholder = thumbnailPlaceholder(),
modifier = Modifier.size(JetcasterAppDefaults.thumbnailSize.podcast)
Thumbnail(
podcastInfo = podcastInfo,
size = JetcasterAppDefaults.thumbnailSize.podcast
)
}
},
title = {
Text(text = podcast.title, modifier = Modifier.padding(top = 12.dp))
Text(text = podcastInfo.title, modifier = Modifier.padding(top = 12.dp))
},
modifier = modifier,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import com.example.jetcaster.core.data.database.model.Podcast
import com.example.jetcaster.core.model.PlayerEpisode
import com.example.jetcaster.core.model.PodcastInfo
import com.example.jetcaster.designsystem.component.PodcastImage
import com.example.jetcaster.tv.ui.theme.JetcasterAppDefaults

@Composable
fun Thumbnail(
podcast: Podcast,
podcastInfo: PodcastInfo,
modifier: Modifier = Modifier,
shape: RoundedCornerShape = RoundedCornerShape(12.dp),
size: DpSize = DpSize(
Expand All @@ -41,7 +41,7 @@ fun Thumbnail(
contentScale: ContentScale = ContentScale.Crop
) =
Thumbnail(
podcast.imageUrl,
podcastInfo.imageUrl,
modifier,
shape,
size,
Expand Down Expand Up @@ -69,7 +69,7 @@ fun Thumbnail(

@Composable
fun Thumbnail(
url: String?,
url: String,
modifier: Modifier = Modifier,
shape: RoundedCornerShape = RoundedCornerShape(12.dp),
size: DpSize = DpSize(
Expand All @@ -78,12 +78,11 @@ fun Thumbnail(
),
contentScale: ContentScale = ContentScale.Crop
) =
AsyncImage(
model = url,
PodcastImage(
podcastImageUrl = url,
contentDescription = null,
contentScale = contentScale,
modifier = Modifier
.size(size)
modifier = modifier
.clip(shape)
.then(modifier)
.size(size),
)
Loading

0 comments on commit 359e278

Please sign in to comment.