Skip to content

Commit

Permalink
Changes MediaUiModel to use Paintable
Browse files Browse the repository at this point in the history
  • Loading branch information
fstanis committed Apr 9, 2024
1 parent 254b401 commit f72cfe6
Show file tree
Hide file tree
Showing 14 changed files with 74 additions and 38 deletions.
2 changes: 1 addition & 1 deletion images/coil/api/current.api
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
package com.google.android.horologist.images.coil {

public final class ArtworkColorKt {
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> rememberArtworkColor(String? artworkUri, optional long defaultColor);
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> rememberArtworkColor(Object? model, optional long defaultColor);
}

@androidx.compose.runtime.Stable public final class CoilPaintable implements com.google.android.horologist.images.base.paintable.Paintable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,19 @@ import com.google.android.horologist.annotations.ExperimentalHorologistApi
@Composable
@ExperimentalHorologistApi
public fun rememberArtworkColor(
artworkUri: String?,
model: Any?,
defaultColor: Color = MaterialTheme.colors.primary,
): State<Color> {
val context = LocalContext.current
val imageLoader = context.imageLoader

val artworkColor = remember { mutableStateOf(defaultColor) }

LaunchedEffect(artworkUri) {
artworkColor.value = if (artworkUri != null) {
LaunchedEffect(model) {
artworkColor.value = if (model != null) {
val request =
ImageRequest.Builder(context)
.data(artworkUri)
.data(model)
.allowHardware(false)
.build()
val result = imageLoader.execute(request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.wear.compose.material.MaterialTheme
import com.google.android.horologist.audio.ui.VolumeViewModel
import com.google.android.horologist.images.coil.CoilPaintable
import com.google.android.horologist.media.ui.components.PodcastControlButtons
import com.google.android.horologist.media.ui.components.animated.AnimatedMediaControlButtons
import com.google.android.horologist.media.ui.components.animated.AnimatedMediaInfoDisplay
import com.google.android.horologist.media.ui.components.background.ArtworkColorBackground
import com.google.android.horologist.media.ui.components.background.ColorBackground
import com.google.android.horologist.media.ui.screens.player.DefaultMediaInfoDisplay
import com.google.android.horologist.media.ui.screens.player.DefaultPlayerScreenControlButtons
import com.google.android.horologist.media.ui.screens.player.PlayerScreen
Expand All @@ -49,12 +51,19 @@ fun UampMediaPlayerScreen(
PlayerScreen(
modifier = modifier,
background = {
val artworkUri = it.media?.artworkUri
ArtworkColorBackground(
artworkUri = artworkUri,
defaultColor = MaterialTheme.colors.primary,
modifier = Modifier.fillMaxSize(),
)
val artworkColor = it.media?.artworkColor
if (artworkColor != null) {
ColorBackground(
color = artworkColor,
modifier = Modifier.fillMaxSize(),
)
} else {
ArtworkColorBackground(
paintable = it.media?.artwork as? CoilPaintable,
defaultColor = MaterialTheme.colors.primary,
modifier = Modifier.fillMaxSize(),
)
}
},
playerViewModel = mediaPlayerScreenViewModel,
volumeViewModel = volumeViewModel,
Expand Down
13 changes: 7 additions & 6 deletions media/ui/api/current.api
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ package com.google.android.horologist.media.ui.components {
}

public final class MediaArtworkKt {
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void MediaArtwork(androidx.compose.ui.graphics.painter.Painter painter, String? contentDescription, optional androidx.compose.ui.Modifier modifier);
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void MediaArtwork(com.google.android.horologist.images.base.paintable.Paintable artworkPaintable, String? contentDescription, optional androidx.compose.ui.Modifier modifier);
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void MediaArtwork(com.google.android.horologist.media.ui.state.model.MediaUiModel media, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.painter.Painter? placeholder);
}
Expand Down Expand Up @@ -133,7 +134,7 @@ package com.google.android.horologist.media.ui.components.animated {
package com.google.android.horologist.media.ui.components.background {

public final class ArtworkColorBackgroundKt {
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void ArtworkColorBackground(String? artworkUri, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Color? defaultColor, optional long background);
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void ArtworkColorBackground(com.google.android.horologist.images.coil.CoilPaintable? paintable, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Color? defaultColor, optional long background);
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static void ColorBackground(androidx.compose.ui.graphics.Color? color, optional androidx.compose.ui.Modifier modifier, optional long background);
method @androidx.compose.runtime.Composable @com.google.android.horologist.annotations.ExperimentalHorologistApi public static androidx.compose.runtime.State<androidx.compose.ui.graphics.Brush> rememberArtworkColorBrush(long artworkColor, optional long background);
}
Expand Down Expand Up @@ -769,23 +770,23 @@ package com.google.android.horologist.media.ui.state.model {
}

@com.google.android.horologist.annotations.ExperimentalHorologistApi public final class MediaUiModel {
ctor public MediaUiModel(String id, String title, optional String subtitle, optional String? artworkUri, optional androidx.compose.ui.graphics.Color? artworkColor, optional com.google.android.horologist.images.base.paintable.Paintable? titleIcon);
ctor public MediaUiModel(String id, String title, optional String subtitle, optional com.google.android.horologist.images.base.paintable.Paintable? artwork, optional androidx.compose.ui.graphics.Color? artworkColor, optional com.google.android.horologist.images.base.paintable.Paintable? titleIcon);
method public String component1();
method public String component2();
method public String component3();
method public String? component4();
method public com.google.android.horologist.images.base.paintable.Paintable? component4();
method public androidx.compose.ui.graphics.Color? component5-QN2ZGVo();
method public com.google.android.horologist.images.base.paintable.Paintable? component6();
method public com.google.android.horologist.media.ui.state.model.MediaUiModel copy-gCxFOHY(String id, String title, String subtitle, String? artworkUri, androidx.compose.ui.graphics.Color? artworkColor, com.google.android.horologist.images.base.paintable.Paintable? titleIcon);
method public com.google.android.horologist.media.ui.state.model.MediaUiModel copy-gCxFOHY(String id, String title, String subtitle, com.google.android.horologist.images.base.paintable.Paintable? artwork, androidx.compose.ui.graphics.Color? artworkColor, com.google.android.horologist.images.base.paintable.Paintable? titleIcon);
method public com.google.android.horologist.images.base.paintable.Paintable? getArtwork();
method public androidx.compose.ui.graphics.Color? getArtworkColor();
method public String? getArtworkUri();
method public String getId();
method public boolean getLoading();
method public String getSubtitle();
method public String getTitle();
method public com.google.android.horologist.images.base.paintable.Paintable? getTitleIcon();
property public final com.google.android.horologist.images.base.paintable.Paintable? artwork;
property public final androidx.compose.ui.graphics.Color? artworkColor;
property public final String? artworkUri;
property public final String id;
property public final boolean loading;
property public final String subtitle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fun MediaArtworkPreview() {
media = MediaUiModel(
id = "id",
title = "title",
artworkUri = "artworkUri",
artwork = null,
),
placeholder = rememberVectorPainter(image = Icons.Default.Album),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fun MediaChipPreview() {
media = MediaUiModel(
id = "id",
title = "Red Hot Chilli Peppers",
artworkUri = "artworkUri",
artwork = null,
),
onClick = {},
placeholder = rememberVectorPainter(
Expand Down Expand Up @@ -67,7 +67,7 @@ fun MediaChipPreviewNoArtwork() {
@Composable
fun MediaChipPreviewNoTitle() {
MediaChip(
media = MediaUiModel(id = "id", title = "title", artworkUri = "artworkUri"),
media = MediaUiModel(id = "id", title = "title", artwork = null),
onClick = {},
defaultTitle = "No title",
placeholder = rememberVectorPainter(
Expand All @@ -88,7 +88,7 @@ fun MediaChipPreviewVeryLongTitle() {
media = MediaUiModel(
id = "id",
title = "Very very very very very very very very very very very very very very very very very very very long title",
artworkUri = "artworkUri",
artwork = null,
),
onClick = {},
placeholder = rememberVectorPainter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import com.google.android.horologist.annotations.ExperimentalHorologistApi
import com.google.android.horologist.images.base.paintable.Paintable
import com.google.android.horologist.images.coil.CoilPaintable
import com.google.android.horologist.media.ui.state.model.MediaUiModel

@ExperimentalHorologistApi
Expand All @@ -33,11 +32,14 @@ public fun MediaArtwork(
modifier: Modifier = Modifier,
placeholder: Painter? = null,
) {
MediaArtwork(
artworkPaintable = CoilPaintable(media.artworkUri, placeholder),
contentDescription = media.title,
modifier = modifier,
)
val painter = media.artwork?.rememberPainter() ?: placeholder
if (painter != null) {
MediaArtwork(
painter = painter,
contentDescription = media.title,
modifier = modifier,
)
}
}

@ExperimentalHorologistApi
Expand All @@ -54,3 +56,18 @@ public fun MediaArtwork(
contentScale = ContentScale.Fit,
)
}

@ExperimentalHorologistApi
@Composable
public fun MediaArtwork(
painter: Painter,
contentDescription: String?,
modifier: Modifier = Modifier,
) {
Image(
modifier = modifier,
painter = painter,
contentDescription = contentDescription,
contentScale = ContentScale.Fit,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ import com.google.android.horologist.media.ui.state.model.MediaUiModel
* A rounded chip to show a single [MediaUiModel].
*
* @param media The [MediaUiModel] that the [title][MediaUiModel.title] and
* [artwork][MediaUiModel.artworkUri] will be used to display on the chip.
* [artwork][MediaUiModel.artwork] will be used to display on the chip.
* @param onClick Will be called when the user clicks the chip.
* @param modifier The Modifier to be applied to the chip.
* @param defaultTitle A text to be used when [MediaUiModel.title] is null.
* @param placeholder A placeholder image to be displayed while
* [artwork][MediaUiModel.artworkUri] is being loaded.
* [artwork][MediaUiModel.artwork] is being loaded.
*/
@ExperimentalHorologistApi
@Composable
Expand All @@ -53,7 +53,7 @@ public fun MediaChip(
defaultTitle: String = "",
placeholder: Painter? = null,
) {
val artworkUri = media.artworkUri
val artworkUri = media.artwork
val title = media.title

MediaChip(
Expand All @@ -80,7 +80,7 @@ public fun MediaChip(
MediaArtwork(
modifier = Modifier.size(ChipDefaults.LargeIconSize),
contentDescription = title,
artworkPaintable = artworkPaintable,
artworkPaintable = it,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import androidx.compose.ui.graphics.RadialGradientShader
import androidx.compose.ui.graphics.compositeOver
import androidx.wear.compose.material.MaterialTheme
import com.google.android.horologist.annotations.ExperimentalHorologistApi
import com.google.android.horologist.images.coil.CoilPaintable
import com.google.android.horologist.images.coil.rememberArtworkColor

/**
Expand All @@ -45,13 +46,13 @@ import com.google.android.horologist.images.coil.rememberArtworkColor
@Composable
@ExperimentalHorologistApi
public fun ArtworkColorBackground(
artworkUri: String?,
paintable: CoilPaintable?,
modifier: Modifier = Modifier,
defaultColor: Color? = null,
background: Color = MaterialTheme.colors.background,
) {
val artworkColor = rememberArtworkColor(
artworkUri = artworkUri,
model = paintable?.model,
defaultColor = defaultColor ?: Color.Black,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package com.google.android.horologist.media.ui.state.mapper

import androidx.compose.ui.graphics.Color
import com.google.android.horologist.annotations.ExperimentalHorologistApi
import com.google.android.horologist.images.coil.CoilPaintable
import com.google.android.horologist.media.model.Media
import com.google.android.horologist.media.ui.state.model.MediaUiModel

Expand All @@ -38,7 +39,7 @@ public object MediaUiModelMapper {
id = media.id,
title = title,
subtitle = artist,
artworkUri = media.artworkUri,
artwork = media.artworkUri?.let { CoilPaintable(it) },
artworkColor = media.artworkColor?.let { Color(it) },
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public data class MediaUiModel(
val id: String,
val title: String,
val subtitle: String = "",
val artworkUri: String? = null,
val artwork: Paintable? = null,
val artworkColor: Color? = null,
val titleIcon: Paintable? = null,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import coil.annotation.ExperimentalCoilApi
import coil.decode.DataSource
import coil.request.SuccessResult
import coil.test.FakeImageLoaderEngine
import com.google.android.horologist.images.coil.CoilPaintable
import com.google.android.horologist.images.coil.FakeImageLoader
import com.google.android.horologist.media.ui.state.model.MediaUiModel
import com.google.android.horologist.screenshots.rng.WearLegacyA11yTest
Expand Down Expand Up @@ -62,7 +63,7 @@ class MediaArtworkA11yTest : WearLegacyA11yTest() {
media = MediaUiModel(
id = "id",
title = "title",
artworkUri = FakeImageLoader.TestIconResourceUri,
artwork = CoilPaintable(FakeImageLoader.TestIconResourceUri),
),
placeholder = rememberVectorPainter(image = Icons.Default.Album),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import coil.annotation.ExperimentalCoilApi
import coil.decode.DataSource
import coil.request.SuccessResult
import coil.test.FakeImageLoaderEngine
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.google.android.horologist.images.coil.CoilPaintable
import com.google.android.horologist.images.coil.FakeImageLoader
import com.google.android.horologist.media.ui.state.model.MediaUiModel
import com.google.android.horologist.screenshots.rng.WearLegacyA11yTest
Expand Down Expand Up @@ -55,7 +60,7 @@ class MediaChipA11yTest : WearLegacyA11yTest() {
media = MediaUiModel(
id = "id",
title = "Red Hot Chilli Peppers",
artworkUri = FakeImageLoader.TestIconResourceUri,
artwork = CoilPaintable(FakeImageLoader.TestIconResourceUri),
),
onClick = {},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.android.horologist.media.ui.state.mapper

import com.google.android.horologist.images.coil.CoilPaintable
import com.google.android.horologist.media.model.Media
import com.google.common.truth.Truth.assertThat
import org.junit.Test
Expand Down Expand Up @@ -44,6 +45,6 @@ class MediaUiModelMapperTest {
assertThat(result.id).isEqualTo(id)
assertThat(result.title).isEqualTo(title)
assertThat(result.subtitle).isEqualTo(artist)
assertThat(result.artworkUri).isEqualTo(artworkUri)
assertThat(result.artwork).isEqualTo(CoilPaintable(artworkUri))
}
}

0 comments on commit f72cfe6

Please sign in to comment.