Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions documentation/internal/sdk-knowledge/native/android.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,6 @@ viewportHeight }` via `LocalScrollContext` that descendant `Modifier.trackViews`
`com.squareup.okhttp3:okhttp-android:5.1.0` as a direct `implementation` so consumers do not hit
`ClassNotFoundException: okhttp3.OkHttpClient` at runtime (the parent `okhttp:5.x` module is KMP
metadata only). source: extern:OptimizedEntry CDAEntry overload wraps the live entry in a CTEntry — packages/android/ContentfulOptimization/src/main/kotlin/com/contentful/optimization/compose/OptimizedEntry.kt#OptimizedEntry; extern:OptimizedEntryView.setEntry(CDAEntry) wraps in CTEntry.from(entry).toMap() — packages/android/ContentfulOptimization/src/main/kotlin/com/contentful/optimization/views/OptimizedEntryView.kt#OptimizedEntryView; extern:contentful.java is compileOnly with okhttp-jvm exclusion + okhttp-android direct implementation — packages/android/ContentfulOptimization/build.gradle.kts
- `CTEntry.imageURL: String?` is a top-level extension property that reads
`getField<Map<String, Any?>>("image")?["fields"]?["file"]?["url"]`, returns `null` when any layer
is missing, and rewrites protocol-relative Contentful Asset URLs (`//images.ctfassets.net/...`)
to `https:` — Android image loaders reject the scheme-less form. Absolute URLs pass through
unchanged. source: extern:CTEntry.imageURL extension property — packages/android/ContentfulOptimization/src/main/kotlin/com/contentful/optimization/contentful/CTEntry.kt#imageURL

## Identifier ownership

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,17 +236,6 @@ public class CTEntry internal constructor(private val entry: Entry) {
}
}

// Protocol-relative Contentful Asset URLs (`//images.ctfassets.net/...`) resolve in browsers but
// crash Android URL loaders that expect a scheme; prepend https so image loaders can consume it.
public val CTEntry.imageURL: String?
get() {
val image = getField<Map<String, Any?>>("image") ?: return null
val fields = image["fields"] as? Map<*, *> ?: return null
val file = fields["file"] as? Map<*, *> ?: return null
val url = file["url"] as? String ?: return null
return if (url.startsWith("//")) "https:$url" else url
}

private sealed class Field {
abstract fun encoded(): JSONValue?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,55 +86,6 @@ class CTEntryTest {
assertNull(entry["nope"])
}

@Test
fun `imageURL prepends https to protocol-relative asset URLs`() {
val entry = CTEntry.from(mapOf(
"sys" to mapOf("id" to "e1"),
"fields" to mapOf(
"image" to mapOf(
"sys" to mapOf("id" to "a1", "type" to "Asset"),
"fields" to mapOf(
"file" to mapOf("url" to "//images.ctfassets.net/x/photo.jpg"),
),
),
),
))
assertEquals("https://images.ctfassets.net/x/photo.jpg", entry.imageURL)
}

@Test
fun `imageURL returns absolute URL as-is`() {
val entry = CTEntry.from(mapOf(
"sys" to mapOf("id" to "e1"),
"fields" to mapOf(
"image" to mapOf(
"sys" to mapOf("id" to "a1", "type" to "Asset"),
"fields" to mapOf(
"file" to mapOf("url" to "https://cdn.example/photo.jpg"),
),
),
),
))
assertEquals("https://cdn.example/photo.jpg", entry.imageURL)
}

@Test
fun `imageURL returns null when the image field or nested shape is missing`() {
val noImage = CTEntry.from(mapOf("sys" to mapOf("id" to "e1"), "fields" to mapOf("title" to "Hello")))
assertNull(noImage.imageURL)

val noFile = CTEntry.from(mapOf(
"sys" to mapOf("id" to "e1"),
"fields" to mapOf(
"image" to mapOf(
"sys" to mapOf("id" to "a1", "type" to "Asset"),
"fields" to mapOf("title" to "Only a title"),
),
),
))
assertNull(noFile.imageURL)
}

@Test
fun `from(any) with an unserializable value falls back to an empty CTEntry`() {
val nonJsonSafe = mapOf<String, Any>(
Expand Down