diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1abdb3a51..a8e907001 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ accompanist = "0.33.0-alpha" activityCompose = "1.8.0" androidGradlePlugin = "8.1.2" coil = "2.5.0" -dataProvider = "0.6.2" +dataProvider = "0.7.7" kotlinPlugin = "1.9.10" detekt = "1.23.3" # https://github.com/detekt/detekt kotlinxSerializationJson = "1.6.0" diff --git a/pillarbox-core-business/src/androidTest/java/ch/srgssr/pillarbox/core/business/CommandersActTrackerTest.kt b/pillarbox-core-business/src/androidTest/java/ch/srgssr/pillarbox/core/business/CommandersActTrackerTest.kt index e16244449..92cd48feb 100644 --- a/pillarbox-core-business/src/androidTest/java/ch/srgssr/pillarbox/core/business/CommandersActTrackerTest.kt +++ b/pillarbox-core-business/src/androidTest/java/ch/srgssr/pillarbox/core/business/CommandersActTrackerTest.kt @@ -12,7 +12,6 @@ import ch.srgssr.pillarbox.analytics.commandersact.CommandersAct import ch.srgssr.pillarbox.analytics.commandersact.CommandersActPageView import ch.srgssr.pillarbox.analytics.commandersact.MediaEventType import ch.srgssr.pillarbox.analytics.commandersact.TCMediaEvent -import ch.srgssr.pillarbox.core.business.images.DefaultImageScalingService import ch.srgssr.pillarbox.core.business.tracker.DefaultMediaItemTrackerRepository import ch.srgssr.pillarbox.core.business.tracker.commandersact.CommandersActStreaming import ch.srgssr.pillarbox.player.PillarboxPlayer @@ -47,7 +46,6 @@ class CommandersActTrackerTest { context = context, mediaItemSource = MediaCompositionMediaItemSource( mediaCompositionDataSource = LocalMediaCompositionDataSource(context), - imageScalingService = DefaultImageScalingService() ), mediaItemTrackerProvider = DefaultMediaItemTrackerRepository( trackerRepository = MediaItemTrackerRepository(), diff --git a/pillarbox-core-business/src/androidTest/java/ch/srgssr/pillarbox/core/business/images/DefaultImageScalingServiceTest.kt b/pillarbox-core-business/src/androidTest/java/ch/srgssr/pillarbox/core/business/images/DefaultImageScalingServiceTest.kt deleted file mode 100644 index 98960ba80..000000000 --- a/pillarbox-core-business/src/androidTest/java/ch/srgssr/pillarbox/core/business/images/DefaultImageScalingServiceTest.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) SRG SSR. All rights reserved. - * License information is available from the LICENSE file. - */ -package ch.srgssr.pillarbox.core.business.images - -import android.net.Uri -import ch.srgssr.pillarbox.core.business.images.ImageScalingService.ImageFormat -import ch.srgssr.pillarbox.core.business.images.ImageScalingService.ImageWidth -import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlHost -import org.junit.Assert.assertEquals -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.Parameterized -import org.junit.runners.Parameterized.Parameters -import java.net.URL - -@RunWith(Parameterized::class) -class DefaultImageScalingServiceTest( - private val baseUrl: URL, - private val imageUrl: String, - private val width: ImageWidth, - private val format: ImageFormat -) { - private lateinit var imageScalingService: ImageScalingService - - @Before - fun before() { - imageScalingService = DefaultImageScalingService(baseUrl) - } - - @Test - fun getScaledImageUrl() { - val scaledImageUrl = imageScalingService.getScaledImageUrl(imageUrl, width, format) - val encodedImageUrl = Uri.encode(imageUrl) - - assertEquals("${baseUrl}images/?imageUrl=$encodedImageUrl&format=${format.format}&width=${width.width}", scaledImageUrl) - } - - companion object { - @JvmStatic - @Parameters - fun parameters(): Iterable { - return listOf( - arrayOf(IlHost.PROD, "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9", ImageWidth.W240, ImageFormat.JPG), - arrayOf(IlHost.TEST, "https://www.rts.ch/2021/08/05/18/12/12396566.image/2x3", ImageWidth.W320, ImageFormat.PNG), - arrayOf(IlHost.STAGE, "https://www.rts.ch/2022/10/06/17/32/13444418.image/4x5", ImageWidth.W480, ImageFormat.WEBP) - ) - } - } -} diff --git a/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/DefaultPillarbox.kt b/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/DefaultPillarbox.kt index 444def110..989afdb19 100644 --- a/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/DefaultPillarbox.kt +++ b/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/DefaultPillarbox.kt @@ -9,7 +9,6 @@ import androidx.media3.datasource.DataSource import androidx.media3.exoplayer.DefaultLoadControl import androidx.media3.exoplayer.LoadControl import ch.srgssr.pillarbox.core.business.akamai.AkamaiTokenDataSource -import ch.srgssr.pillarbox.core.business.images.DefaultImageScalingService import ch.srgssr.pillarbox.core.business.integrationlayer.service.DefaultMediaCompositionDataSource import ch.srgssr.pillarbox.core.business.tracker.DefaultMediaItemTrackerRepository import ch.srgssr.pillarbox.player.PillarboxPlayer @@ -41,7 +40,6 @@ object DefaultPillarbox { mediaItemTrackerRepository: MediaItemTrackerProvider = DefaultMediaItemTrackerRepository(), mediaItemSource: MediaItemSource = MediaCompositionMediaItemSource( mediaCompositionDataSource = DefaultMediaCompositionDataSource(), - imageScalingService = DefaultImageScalingService() ), dataSourceFactory: DataSource.Factory = AkamaiTokenDataSource.Factory(), loadControl: LoadControl = DefaultLoadControl(), diff --git a/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/MediaCompositionMediaItemSource.kt b/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/MediaCompositionMediaItemSource.kt index a528340c5..3152d944e 100644 --- a/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/MediaCompositionMediaItemSource.kt +++ b/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/MediaCompositionMediaItemSource.kt @@ -5,21 +5,21 @@ package ch.srgssr.pillarbox.core.business import android.net.Uri +import androidx.annotation.Px import androidx.core.net.toUri import androidx.media3.common.C import androidx.media3.common.MediaItem import androidx.media3.common.MediaMetadata +import ch.srgssr.pillarbox.core.business.MediaCompositionMediaItemSource.ImageScalingService.ImageWidth import ch.srgssr.pillarbox.core.business.exception.BlockReasonException import ch.srgssr.pillarbox.core.business.exception.DataParsingException import ch.srgssr.pillarbox.core.business.exception.ResourceNotFoundException -import ch.srgssr.pillarbox.core.business.images.ImageScalingService -import ch.srgssr.pillarbox.core.business.images.ImageScalingService.ImageFormat -import ch.srgssr.pillarbox.core.business.images.ImageScalingService.ImageWidth import ch.srgssr.pillarbox.core.business.integrationlayer.data.Chapter import ch.srgssr.pillarbox.core.business.integrationlayer.data.Drm import ch.srgssr.pillarbox.core.business.integrationlayer.data.MediaComposition import ch.srgssr.pillarbox.core.business.integrationlayer.data.MediaUrn import ch.srgssr.pillarbox.core.business.integrationlayer.data.Resource +import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlHost import ch.srgssr.pillarbox.core.business.integrationlayer.service.MediaCompositionDataSource import ch.srgssr.pillarbox.core.business.tracker.SRGEventLoggerTracker import ch.srgssr.pillarbox.core.business.tracker.commandersact.CommandersActTracker @@ -28,8 +28,11 @@ import ch.srgssr.pillarbox.player.data.MediaItemSource import ch.srgssr.pillarbox.player.extension.getMediaItemTrackerData import ch.srgssr.pillarbox.player.extension.setTrackerData import io.ktor.client.plugins.ClientRequestException +import io.ktor.http.URLBuilder +import io.ktor.http.appendEncodedPathSegments import kotlinx.serialization.SerializationException import java.io.IOException +import java.net.URL /** * Load [MediaItem] playable from a [ch.srgssr.pillarbox.core.business.integrationlayer.data.MediaComposition] @@ -41,15 +44,14 @@ import java.io.IOException * - [MediaMetadata.description] with [Chapter.description] * * @param mediaCompositionDataSource The MediaCompositionDataSource to use to load a MediaComposition. - * @param imageScalingService The ImageScaleService to use to get a scaled image. * @param trackerDataProvider The TrackerDataProvider to customize TrackerData. */ class MediaCompositionMediaItemSource( private val mediaCompositionDataSource: MediaCompositionDataSource, - private val imageScalingService: ImageScalingService, private val trackerDataProvider: TrackerDataProvider? = null ) : MediaItemSource { private val resourceSelector = ResourceSelector() + private val imageScalingService = ImageScalingService() private fun fillMetaData(metadata: MediaMetadata, chapter: Chapter): MediaMetadata { val builder = metadata.buildUpon() @@ -60,7 +62,6 @@ class MediaCompositionMediaItemSource( val artworkUri = imageScalingService.getScaledImageUrl( imageUrl = chapter.imageUrl, width = ImageWidth.W480, - format = ImageFormat.WEBP ).toUri() builder.setArtworkUri(artworkUri) @@ -131,7 +132,7 @@ class MediaCompositionMediaItemSource( /** * Select a [Resource] from [Chapter.listResource] */ - class ResourceSelector { + internal class ResourceSelector { /** * Select the first resource from chapter that is playable by the Player. * @@ -151,6 +152,43 @@ class MediaCompositionMediaItemSource( } } + /** + * Service used to get a scaled image URL. This only works for SRG images. + * + * @param baseUrl Base URL of the service. + */ + internal class ImageScalingService( + private val baseUrl: URL = IlHost.DEFAULT + ) { + /** + * The supported widths. + * + * @property width The width in pixels. + */ + enum class ImageWidth(@Px val width: Int) { + W240(width = 240), + W320(width = 320), + W480(width = 480), + W960(width = 960), + W1920(width = 1920) + } + + fun getScaledImageUrl( + imageUrl: String, + width: ImageWidth, + ): String { + return URLBuilder(baseUrl.toString()) + .appendEncodedPathSegments("images/") + .apply { + parameters.append("imageUrl", imageUrl) + parameters.append("format", "webp") + parameters.append("width", width.width.toString()) + } + .build() + .toString() + } + } + companion object { /** * Token Query Param to add to trigger token request diff --git a/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/images/DefaultImageScalingService.kt b/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/images/DefaultImageScalingService.kt deleted file mode 100644 index ded9cad2e..000000000 --- a/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/images/DefaultImageScalingService.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) SRG SSR. All rights reserved. - * License information is available from the LICENSE file. - */ -package ch.srgssr.pillarbox.core.business.images - -import android.net.Uri -import ch.srgssr.pillarbox.core.business.images.ImageScalingService.ImageFormat -import ch.srgssr.pillarbox.core.business.images.ImageScalingService.ImageWidth -import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlHost -import java.net.URL - -/** - * Default service for scaling images. This only works for SRG images. - * - * @param baseUrl Base URL of the service. - */ -class DefaultImageScalingService( - private val baseUrl: URL = IlHost.DEFAULT -) : ImageScalingService { - override fun getScaledImageUrl( - imageUrl: String, - width: ImageWidth, - format: ImageFormat - ): String { - return Uri.parse(baseUrl.toString()) - .buildUpon() - .appendEncodedPath("images/") - .appendQueryParameter("imageUrl", imageUrl) - .appendQueryParameter("format", format.format) - .appendQueryParameter("width", width.width.toString()) - .build() - .toString() - } -} diff --git a/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/images/ImageScalingService.kt b/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/images/ImageScalingService.kt deleted file mode 100644 index a0b126f31..000000000 --- a/pillarbox-core-business/src/main/java/ch/srgssr/pillarbox/core/business/images/ImageScalingService.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) SRG SSR. All rights reserved. - * License information is available from the LICENSE file. - */ -package ch.srgssr.pillarbox.core.business.images - -import androidx.annotation.Px - -/** - * Service used to get a scaled image URL. - */ -interface ImageScalingService { - /** - * The supported widths. - * - * @property width The width in pixels. - */ - enum class ImageWidth(@Px val width: Int) { - W240(width = 240), - W320(width = 320), - W480(width = 480), - W960(width = 960), - W1920(width = 1920) - } - - /** - * The supported image formats. - * - * @property format The format name. - */ - enum class ImageFormat(val format: String) { - JPG(format = "jpg"), - PNG(format = "png"), - WEBP(format = "webp") - } - - /** - * Get the URL of the scaled image, at the specified size and format, keeping the aspect ratio. - * - * @param imageUrl The original image URL. - * @param width The desired width of the image. - * @param format The desired format of the image. - * - * @return The URL of the scaled image. - */ - fun getScaledImageUrl( - imageUrl: String, - width: ImageWidth, - format: ImageFormat - ): String -} diff --git a/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/ImageScalingServiceTest.kt b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/ImageScalingServiceTest.kt new file mode 100644 index 000000000..99236c140 --- /dev/null +++ b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/ImageScalingServiceTest.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) SRG SSR. All rights reserved. + * License information is available from the LICENSE file. + */ +package ch.srgssr.pillarbox.core.business + +import ch.srgssr.pillarbox.core.business.MediaCompositionMediaItemSource.ImageScalingService +import ch.srgssr.pillarbox.core.business.MediaCompositionMediaItemSource.ImageScalingService.ImageWidth +import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlHost +import org.junit.Assert.assertEquals +import org.junit.Test +import java.net.URLEncoder + +class ImageScalingServiceTest { + @Test + fun getScaledImageUrlProd() { + val baseUrl = IlHost.PROD + val imageUrl = "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9" + val width = ImageWidth.W240 + + val imageScalingService = ImageScalingService(baseUrl) + val scaledImageUrl = imageScalingService.getScaledImageUrl(imageUrl, width) + val encodedImageUrl = URLEncoder.encode(imageUrl, Charsets.UTF_8) + + assertEquals("${baseUrl}images/?imageUrl=$encodedImageUrl&format=webp&width=${width.width}", scaledImageUrl) + } + + @Test + fun getScaledImageUrlTest() { + val baseUrl = IlHost.TEST + val imageUrl = "https://www.rts.ch/2021/08/05/18/12/12396566.image/2x3" + val width = ImageWidth.W320 + + val imageScalingService = ImageScalingService(baseUrl) + val scaledImageUrl = imageScalingService.getScaledImageUrl(imageUrl, width) + val encodedImageUrl = URLEncoder.encode(imageUrl, Charsets.UTF_8) + + assertEquals("${baseUrl}images/?imageUrl=$encodedImageUrl&format=webp&width=${width.width}", scaledImageUrl) + } + + @Test + fun getScaledImageUrlStage() { + val baseUrl = IlHost.STAGE + val imageUrl = "https://www.rts.ch/2022/10/06/17/32/13444418.image/4x5" + val width = ImageWidth.W480 + + val imageScalingService = ImageScalingService(baseUrl) + val scaledImageUrl = imageScalingService.getScaledImageUrl(imageUrl, width) + val encodedImageUrl = URLEncoder.encode(imageUrl, Charsets.UTF_8) + + assertEquals("${baseUrl}images/?imageUrl=$encodedImageUrl&format=webp&width=${width.width}", scaledImageUrl) + } +} diff --git a/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/MediaCompositionMediaItemSourceTest.kt b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/MediaCompositionMediaItemSourceTest.kt index 1095dc30c..c25c77e02 100644 --- a/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/MediaCompositionMediaItemSourceTest.kt +++ b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/MediaCompositionMediaItemSourceTest.kt @@ -8,7 +8,6 @@ import androidx.media3.common.MediaItem import androidx.media3.common.MediaMetadata import ch.srgssr.pillarbox.core.business.exception.BlockReasonException import ch.srgssr.pillarbox.core.business.exception.ResourceNotFoundException -import ch.srgssr.pillarbox.core.business.images.ImageScalingService import ch.srgssr.pillarbox.core.business.integrationlayer.data.BlockReason import ch.srgssr.pillarbox.core.business.integrationlayer.data.Chapter import ch.srgssr.pillarbox.core.business.integrationlayer.data.MediaComposition @@ -23,7 +22,6 @@ class MediaCompositionMediaItemSourceTest { private val mediaItemSource = MediaCompositionMediaItemSource( mediaCompositionDataSource = DummyMediaCompositionProvider(), - imageScalingService = NoOpImageScalingService() ) @Test(expected = IllegalArgumentException::class) @@ -186,12 +184,6 @@ class MediaCompositionMediaItemSourceTest { } } - private class NoOpImageScalingService : ImageScalingService { - override fun getScaledImageUrl(imageUrl: String, width: ImageScalingService.ImageWidth, format: ImageScalingService.ImageFormat): String { - return imageUrl - } - } - companion object { private fun createMediaItem(urn: String): MediaItem { return MediaItem.Builder().setMediaId(urn).build() diff --git a/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/di/PlayerModule.kt b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/di/PlayerModule.kt index d9174a3a0..44eb316a4 100644 --- a/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/di/PlayerModule.kt +++ b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/di/PlayerModule.kt @@ -10,8 +10,6 @@ import ch.srg.dataProvider.integrationlayer.dependencies.modules.OkHttpModule import ch.srgssr.dataprovider.paging.DataProviderPaging import ch.srgssr.pillarbox.core.business.DefaultPillarbox import ch.srgssr.pillarbox.core.business.MediaCompositionMediaItemSource -import ch.srgssr.pillarbox.core.business.images.DefaultImageScalingService -import ch.srgssr.pillarbox.core.business.images.ImageScalingService import ch.srgssr.pillarbox.core.business.integrationlayer.service.DefaultMediaCompositionDataSource import ch.srgssr.pillarbox.core.business.integrationlayer.service.IlHost import ch.srgssr.pillarbox.core.business.integrationlayer.service.Vector.getVector @@ -28,7 +26,6 @@ object PlayerModule { private fun provideIntegrationLayerItemSource(context: Context): MediaCompositionMediaItemSource = MediaCompositionMediaItemSource( mediaCompositionDataSource = DefaultMediaCompositionDataSource(vector = context.getVector()), - imageScalingService = provideImageScalingService() ) /** @@ -54,13 +51,6 @@ object PlayerModule { return ILRepository(dataProviderPaging = DataProviderPaging(ilService), ilService = ilService) } - /** - * Provide a default implementation for the image scaling service. - */ - fun provideImageScalingService(): ImageScalingService { - return DefaultImageScalingService() - } - private fun providerIlHostFromUrl(ilHost: URL): ch.srg.dataProvider.integrationlayer.request.IlHost { return when (ilHost) { IlHost.STAGE -> ch.srg.dataProvider.integrationlayer.request.IlHost.STAGE diff --git a/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/ui/integrationLayer/ContentListViewModel.kt b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/ui/integrationLayer/ContentListViewModel.kt index 45dcbace5..a91bf3d5f 100644 --- a/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/ui/integrationLayer/ContentListViewModel.kt +++ b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/ui/integrationLayer/ContentListViewModel.kt @@ -11,11 +11,9 @@ import androidx.lifecycle.viewModelScope import androidx.paging.PagingData import androidx.paging.cachedIn import androidx.paging.map -import ch.srg.dataProvider.integrationlayer.data.IlImage -import ch.srgssr.pillarbox.core.business.images.ImageScalingService -import ch.srgssr.pillarbox.core.business.images.ImageScalingService.ImageFormat -import ch.srgssr.pillarbox.core.business.images.ImageScalingService.ImageWidth -import ch.srgssr.pillarbox.demo.shared.di.PlayerModule +import ch.srg.dataProvider.integrationlayer.data.ImageUrl +import ch.srg.dataProvider.integrationlayer.request.image.ImageWidth +import ch.srg.dataProvider.integrationlayer.request.image.decorated import ch.srgssr.pillarbox.demo.shared.ui.integrationLayer.data.Content import ch.srgssr.pillarbox.demo.shared.ui.integrationLayer.data.ILRepository import kotlinx.coroutines.flow.Flow @@ -27,14 +25,12 @@ import kotlinx.coroutines.flow.map * * @param ilRepository The repository used to load the data from the integration layer. * @param contentList The type of list to display. - * @param imageScalingService The service to scale the image to display. * @constructor Create a new [ContentListViewModel]. */ class ContentListViewModel( private val ilRepository: ILRepository, private val contentList: ContentList, - private val imageScalingService: ImageScalingService ) : ViewModel() { /** @@ -89,23 +85,16 @@ class ContentListViewModel( * * @param imageUrl The original image URL. * @param containerWidth The width, in pixels, of the image container. - * @param format The desired format of the transformed image. * * @return xx */ fun getScaledImageUrl( - imageUrl: String, + imageUrl: ImageUrl, @Px containerWidth: Int, - format: ImageFormat = ImageFormat.WEBP ): String { - val size = IlImage.Size.getClosest(containerWidth) - val width = enumValueOf(size.name) - - return imageScalingService.getScaledImageUrl( - imageUrl = imageUrl, - width = width, - format = format - ) + val width = ImageWidth.getFromPixels(containerWidth) + + return imageUrl.decorated(width = width) } private fun Flow>.mapPaging(transform: (T) -> R): Flow> { @@ -118,10 +107,9 @@ class ContentListViewModel( class Factory( private var ilRepository: ILRepository, private val contentList: ContentList, - private val imageScalingService: ImageScalingService = PlayerModule.provideImageScalingService() ) : ViewModelProvider.NewInstanceFactory() { override fun create(modelClass: Class): T { - return ContentListViewModel(ilRepository, contentList, imageScalingService) as T + return ContentListViewModel(ilRepository, contentList) as T } } } diff --git a/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/ui/integrationLayer/SearchViewModel.kt b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/ui/integrationLayer/SearchViewModel.kt index 52177c6d6..458d091aa 100644 --- a/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/ui/integrationLayer/SearchViewModel.kt +++ b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/ui/integrationLayer/SearchViewModel.kt @@ -13,10 +13,10 @@ import androidx.paging.LoadStates import androidx.paging.PagingData import androidx.paging.cachedIn import androidx.paging.map -import ch.srg.dataProvider.integrationlayer.data.IlImage +import ch.srg.dataProvider.integrationlayer.data.ImageUrl +import ch.srg.dataProvider.integrationlayer.request.image.ImageWidth +import ch.srg.dataProvider.integrationlayer.request.image.decorated import ch.srg.dataProvider.integrationlayer.request.parameters.Bu -import ch.srgssr.pillarbox.core.business.images.ImageScalingService -import ch.srgssr.pillarbox.demo.shared.di.PlayerModule import ch.srgssr.pillarbox.demo.shared.ui.integrationLayer.data.Content import ch.srgssr.pillarbox.demo.shared.ui.integrationLayer.data.ILRepository import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -35,13 +35,11 @@ import kotlin.time.Duration.Companion.milliseconds * [ViewModel] used to search for content in a specific BU. * * @param ilRepository The repository used to load the data from the integration layer. - * @param imageScalingService The service to scale the image to display. * * @constructor Create a new [SearchViewModel]. */ class SearchViewModel( private val ilRepository: ILRepository, - private val imageScalingService: ImageScalingService ) : ViewModel() { private val _bu = MutableStateFlow(Bu.RTS) @@ -134,23 +132,16 @@ class SearchViewModel( * * @param imageUrl The original image URL. * @param containerWidth The width, in pixels, of the image container. - * @param format The desired format of the transformed image. * * @return xx */ fun getScaledImageUrl( - imageUrl: String, + imageUrl: ImageUrl, @Px containerWidth: Int, - format: ImageScalingService.ImageFormat = ImageScalingService.ImageFormat.WEBP ): String { - val size = IlImage.Size.getClosest(containerWidth) - val width = enumValueOf(size.name) + val width = ImageWidth.getFromPixels(containerWidth) - return imageScalingService.getScaledImageUrl( - imageUrl = imageUrl, - width = width, - format = format - ) + return imageUrl.decorated(width = width) } internal data class Config(val bu: Bu, val query: String) @@ -158,10 +149,9 @@ class SearchViewModel( @Suppress("UndocumentedPublicClass") class Factory( private var ilRepository: ILRepository, - private val imageScalingService: ImageScalingService = PlayerModule.provideImageScalingService() ) : ViewModelProvider.NewInstanceFactory() { override fun create(modelClass: Class): T { - return SearchViewModel(ilRepository, imageScalingService) as T + return SearchViewModel(ilRepository) as T } } diff --git a/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/ui/integrationLayer/data/Content.kt b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/ui/integrationLayer/data/Content.kt index ecafeaec6..d110fce5a 100644 --- a/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/ui/integrationLayer/data/Content.kt +++ b/pillarbox-demo-shared/src/main/java/ch/srgssr/pillarbox/demo/shared/ui/integrationLayer/data/Content.kt @@ -41,7 +41,7 @@ sealed interface Content { /** * @property imageUrl The image URL of the media. */ - val imageUrl = media.imageUrl.rawUrl + val imageUrl = media.imageUrl /** * @property mediaType The type of media. @@ -78,7 +78,7 @@ sealed interface Content { /** * @property imageUrl The image URL of the show. */ - val imageUrl = show.imageUrl.rawUrl + val imageUrl = show.imageUrl /** * @property title The title of the show. @@ -105,7 +105,7 @@ sealed interface Content { /** * @property imageUrl The image URL of the topic. */ - val imageUrl = topic.imageUrl?.rawUrl + val imageUrl = topic.imageUrl /** * @property title The title of the topic. diff --git a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/ui/integrationLayer/ListsHome.kt b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/ui/integrationLayer/ListsHome.kt index 34d57082d..3a723f08b 100644 --- a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/ui/integrationLayer/ListsHome.kt +++ b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/ui/integrationLayer/ListsHome.kt @@ -75,6 +75,8 @@ import ch.srg.dataProvider.integrationlayer.data.remote.Topic import ch.srg.dataProvider.integrationlayer.data.remote.Transmission import ch.srg.dataProvider.integrationlayer.data.remote.Type import ch.srg.dataProvider.integrationlayer.data.remote.Vendor +import ch.srg.dataProvider.integrationlayer.request.image.ImageWidth +import ch.srg.dataProvider.integrationlayer.request.image.decorated import ch.srgssr.pillarbox.demo.shared.data.DemoItem import ch.srgssr.pillarbox.demo.shared.di.PlayerModule import ch.srgssr.pillarbox.demo.shared.ui.NavigationRoutes @@ -315,7 +317,7 @@ fun ListsSection( title: String? = null, items: LazyPagingItems, focusFirstItem: Boolean, - scaleImageUrl: (imageUrl: String, containerWidth: Int) -> String, + scaleImageUrl: (imageUrl: ImageUrl, containerWidth: Int) -> String, onItemClick: (item: T) -> Unit, emptyScreen: @Composable (modifier: Modifier) -> Unit ) { @@ -366,7 +368,7 @@ private fun ListsSectionContent( items: LazyPagingItems, modifier: Modifier = Modifier, focusFirstItem: Boolean, - scaleImageUrl: (imageUrl: String, containerWidth: Int) -> String, + scaleImageUrl: (imageUrl: ImageUrl, containerWidth: Int) -> String, onItemClick: (item: T) -> Unit, emptyScreen: @Composable (modifier: Modifier) -> Unit ) { @@ -446,7 +448,7 @@ private fun ListsSectionContent( @Composable private fun ContentCard( item: Content, - scaleImageUrl: (imageUrl: String) -> String, + scaleImageUrl: (imageUrl: ImageUrl) -> String, ) { when (item) { is Content.Media -> MediaContent( @@ -670,7 +672,9 @@ private fun ListsSectionContentPreview() { ListsSectionContent( items = flowOf(PagingData.from(data)).collectAsLazyPagingItems(), focusFirstItem = true, - scaleImageUrl = { imageUrl, _ -> imageUrl }, + scaleImageUrl = { imageUrl, _ -> + imageUrl.decorated(width = ImageWidth.W480) + }, onItemClick = {}, emptyScreen = {} ) diff --git a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/ui/integrationLayer/SearchView.kt b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/ui/integrationLayer/SearchView.kt index aefb52e19..e579b30cd 100644 --- a/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/ui/integrationLayer/SearchView.kt +++ b/pillarbox-demo-tv/src/main/java/ch/srgssr/pillarbox/demo/tv/ui/integrationLayer/SearchView.kt @@ -40,6 +40,8 @@ import androidx.tv.material3.Icon import androidx.tv.material3.LocalContentColor import androidx.tv.material3.MaterialTheme import androidx.tv.material3.Text +import ch.srg.dataProvider.integrationlayer.request.image.ImageWidth +import ch.srg.dataProvider.integrationlayer.request.image.decorated import ch.srg.dataProvider.integrationlayer.request.parameters.Bu import ch.srgssr.pillarbox.demo.shared.R import ch.srgssr.pillarbox.demo.shared.data.DemoItem @@ -89,7 +91,7 @@ fun SearchView( title = item.title, uri = item.urn, description = item.description, - imageUrl = item.imageUrl + imageUrl = item.imageUrl.decorated(width = ImageWidth.W480) ) PlayerActivity.startPlayer(context, demoItem) diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/MainNavigation.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/MainNavigation.kt index f7f154256..02b32671b 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/MainNavigation.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/MainNavigation.kt @@ -39,6 +39,8 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import androidx.navigation.navigation +import ch.srg.dataProvider.integrationlayer.request.image.ImageWidth +import ch.srg.dataProvider.integrationlayer.request.image.decorated import ch.srgssr.pillarbox.analytics.SRGAnalytics import ch.srgssr.pillarbox.demo.DemoPageView import ch.srgssr.pillarbox.demo.shared.data.DemoItem @@ -121,7 +123,7 @@ fun MainNavigation() { title = it.title, uri = it.urn, description = it.description, - imageUrl = it.imageUrl + imageUrl = it.imageUrl.decorated(width = ImageWidth.W480) ) SimplePlayerActivity.startActivity(context, item)