fix(image): register SvgDecoder so SVG logos actually render

Adds the coil-svg KMP module dependency and registers SvgDecoder.Factory()
on the singleton ImageLoader in App.kt. coil-svg was never declared in
libs.versions.toml, so SVG payloads silently fell through Coil's decoder
chain and ended up as empty ImageDecoderException swallowed by AsyncImage.

Coil 3.x's coil-svg is a Kotlin Multiplatform module, so registering the
factory in commonMain covers Android and iOS in one place.

Affects:
- TMDB network/channel logos (TMDB serves a mix of PNG and SVG)
- Stremio addon manifests with an SVG `logo` field
- Custom artwork URLs in the collection editor that happen to be SVG

Mirrors the equivalent fix in NuvioTV (PR #1772).
This commit is contained in:
Stéphane 2026-05-08 19:41:54 +02:00
parent 11a1cf7ba9
commit d303ac48af
3 changed files with 6 additions and 0 deletions

View file

@ -260,6 +260,7 @@ kotlin {
commonMain.dependencies { commonMain.dependencies {
implementation(libs.coil.compose) implementation(libs.coil.compose)
implementation(libs.coil.network.ktor3) implementation(libs.coil.network.ktor3)
implementation(libs.coil.svg)
implementation("dev.chrisbanes.haze:haze:1.7.2") implementation("dev.chrisbanes.haze:haze:1.7.2")
implementation(libs.compose.runtime) implementation(libs.compose.runtime)
implementation(libs.compose.foundation) implementation(libs.compose.foundation)

View file

@ -73,6 +73,7 @@ import coil3.ImageLoader
import coil3.compose.setSingletonImageLoaderFactory import coil3.compose.setSingletonImageLoaderFactory
import coil3.request.CachePolicy import coil3.request.CachePolicy
import coil3.request.crossfade import coil3.request.crossfade
import coil3.svg.SvgDecoder
import com.nuvio.app.core.build.AppFeaturePolicy import com.nuvio.app.core.build.AppFeaturePolicy
import com.nuvio.app.core.auth.AuthRepository import com.nuvio.app.core.auth.AuthRepository
import com.nuvio.app.core.auth.AuthState import com.nuvio.app.core.auth.AuthState
@ -300,6 +301,9 @@ fun App() {
.crossfade(true) .crossfade(true)
.diskCachePolicy(CachePolicy.ENABLED) .diskCachePolicy(CachePolicy.ENABLED)
.memoryCachePolicy(CachePolicy.ENABLED) .memoryCachePolicy(CachePolicy.ENABLED)
.components {
add(SvgDecoder.Factory())
}
.configurePlatformImageLoader() .configurePlatformImageLoader()
.build() .build()
} }

View file

@ -51,6 +51,7 @@ compose-uiToolingPreview = { module = "org.jetbrains.compose.ui:ui-tooling-previ
coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" } coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" }
coil-gif = { module = "io.coil-kt.coil3:coil-gif", version.ref = "coil" } coil-gif = { module = "io.coil-kt.coil3:coil-gif", version.ref = "coil" }
coil-network-ktor3 = { module = "io.coil-kt.coil3:coil-network-ktor3", version.ref = "coil" } coil-network-ktor3 = { module = "io.coil-kt.coil3:coil-network-ktor3", version.ref = "coil" }
coil-svg = { module = "io.coil-kt.coil3:coil-svg", version.ref = "coil" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
ktor-client-android = { module = "io.ktor:ktor-client-android", version.ref = "ktor" } ktor-client-android = { module = "io.ktor:ktor-client-android", version.ref = "ktor" }
kermit = { module = "co.touchlab:kermit", version.ref = "kermit" } kermit = { module = "co.touchlab:kermit", version.ref = "kermit" }