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
33 changes: 22 additions & 11 deletions Sources/SkipUI/SkipUI/Components/AsyncImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import Foundation
#if SKIP
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import android.webkit.MimeTypeMap
import coil3.compose.SubcomposeAsyncImage
import coil3.request.ImageRequest
import coil3.size.Size
import coil3.fetch.Fetcher
import coil3.fetch.FetchResult
import coil3.ImageLoader
Expand Down Expand Up @@ -114,16 +114,27 @@ public struct AsyncImage : View, Renderable {
// we add a custom fetchers that will handle loading the URL.
// Otherwise use Coil's default URL string handling
let requestSource: Any = AssetURLFetcher.handlesURL(url) ? url : urlString
let model = ImageRequest.Builder(LocalContext.current)
.fetcherFactory(AssetURLFetcher.Factory()) // handler for asset:/ and jar:file:/ URLs
.decoderFactory(coil3.svg.SvgDecoder.Factory())
//.decoderFactory(coil3.gif.GifDecoder.Factory())
.decoderFactory(PdfDecoder.Factory())
.data(requestSource)
.size(Size.ORIGINAL)
.memoryCacheKey(urlString)
.diskCacheKey(urlString)
.build()

let androidContext = LocalContext.current
let dm = androidContext.resources.displayMetrics
let maxPx = max(Int(dm.widthPixels), Int(dm.heightPixels))
let cacheKey = "\(urlString)#\(maxPx)x\(maxPx)"
let model = remember(urlString, maxPx) {
// Coil refuses to use its memory cache for .size(Size.ORIGINAL) requests!
// We're using maxPx as an arbitrary bound to force it to cache properly
// Coil memory-cache size validation is in MemoryCacheService.isCacheValueValidForSize:
// See compose-source/io-coil-kt-coil3/coil-core-android/commonMain/coil3/memory/MemoryCacheService.kt:127.
return ImageRequest.Builder(androidContext)
.fetcherFactory(AssetURLFetcher.Factory()) // handler for asset:/ and jar:file:/ URLs
.decoderFactory(coil3.svg.SvgDecoder.Factory())
//.decoderFactory(coil3.gif.GifDecoder.Factory())
.decoderFactory(PdfDecoder.Factory())
.data(requestSource)
.size(coil3.size.Size(width: maxPx, height: maxPx))
.memoryCacheKey(cacheKey)
.diskCacheKey(cacheKey)
.build()
}

SubcomposeAsyncImage(model: model, contentDescription: nil, loading: { _ in
let placeholderView = content(AsyncImagePhase.empty)
Expand Down
32 changes: 22 additions & 10 deletions Sources/SkipUI/SkipUI/Components/Image.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.compose.material.icons.twotone.__
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalTextStyle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.paint
import androidx.compose.ui.geometry.Rect
Expand Down Expand Up @@ -142,16 +143,26 @@ public struct Image : View, Renderable, Equatable {

@Composable private func RenderAssetImage(asset: AssetImageInfo, label: Text?, aspectRatio: Double?, contentMode: ContentMode?, context: ComposeContext) {
let url = asset.url
let model = ImageRequest.Builder(LocalContext.current)
.fetcherFactory(AssetURLFetcher.Factory()) // handler for asset:/ and jar:file:/ URLs
.decoderFactory(coil3.svg.SvgDecoder.Factory())
//.decoderFactory(coil3.gif.GifDecoder.Factory())
.decoderFactory(PdfDecoder.Factory())
.data(url)
.size(coil3.size.Size.ORIGINAL)
.memoryCacheKey(url.description)
.diskCacheKey(url.description)
.build()
let androidContext = LocalContext.current
let dm = androidContext.resources.displayMetrics
let maxPx = max(Int(dm.widthPixels), Int(dm.heightPixels))
let cacheKey = "\(url.description)#\(maxPx)x\(maxPx)"
let model = remember(asset.url, maxPx) {
// Coil refuses to use its memory cache for .size(Size.ORIGINAL) requests!
// We're using maxPx as an arbitrary bound to force it to cache properly
// Coil memory-cache size validation is in MemoryCacheService.isCacheValueValidForSize:
// See compose-source/io-coil-kt-coil3/coil-core-android/commonMain/coil3/memory/MemoryCacheService.kt:127.
return ImageRequest.Builder(androidContext)
.fetcherFactory(AssetURLFetcher.Factory()) // handler for asset:/ and jar:file:/ URLs
.decoderFactory(coil3.svg.SvgDecoder.Factory())
//.decoderFactory(coil3.gif.GifDecoder.Factory())
.decoderFactory(PdfDecoder.Factory())
.data(asset.url)
.size(coil3.size.Size(width: maxPx, height: maxPx))
.memoryCacheKey(cacheKey)
.diskCacheKey(cacheKey)
.build()
}

let shouldTint = (templateRenderingMode == .template) || (templateRenderingMode == nil && asset.isTemplateImage)
let tintColor = shouldTint ? EnvironmentValues.shared._foregroundStyle?.asColor(opacity: 1.0, animationContext: context) ?? Color.primary.colorImpl() : nil
Expand All @@ -161,6 +172,7 @@ public struct Image : View, Renderable, Equatable {
}, success: { state in
RenderPainter(painter: self.painter, tintColor: tintColor, scale: scale, aspectRatio: aspectRatio, contentMode: contentMode, context: context)
}, error: { state in

})
}

Expand Down