diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/UrlCachedPreviewer.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/UrlCachedPreviewer.kt index 9609954ea..5ea62127c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/UrlCachedPreviewer.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/UrlCachedPreviewer.kt @@ -1,26 +1,21 @@ package com.vitorpamplona.amethyst.model +import android.util.LruCache import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.service.previews.BahaUrlPreview import com.vitorpamplona.amethyst.service.previews.IUrlPreviewCallback import com.vitorpamplona.amethyst.service.previews.UrlInfoItem +import com.vitorpamplona.amethyst.ui.components.UrlPreviewState object UrlCachedPreviewer { - var cache = mapOf() - private set - var failures = mapOf() + var cache = LruCache(100) private set - fun previewInfo(url: String, callback: IUrlPreviewCallback? = null) { + fun previewInfo(url: String, onReady: (UrlPreviewState) -> Unit) { checkNotInMainThread() cache[url]?.let { - callback?.onComplete(it) - return - } - - failures[url]?.let { - callback?.onFailed(it) + onReady(it) return } @@ -28,13 +23,32 @@ object UrlCachedPreviewer { url, object : IUrlPreviewCallback { override fun onComplete(urlInfo: UrlInfoItem) { - cache = cache + Pair(url, urlInfo) - callback?.onComplete(urlInfo) + cache[url]?.let { + if (it is UrlPreviewState.Loaded || it is UrlPreviewState.Empty) { + onReady(it) + return + } + } + + val state = if (urlInfo.allFetchComplete() && urlInfo.url == url) { + UrlPreviewState.Loaded(urlInfo) + } else { + UrlPreviewState.Empty + } + + cache.put(url, state) + onReady(state) } override fun onFailed(throwable: Throwable) { - failures = failures + Pair(url, throwable) - callback?.onFailed(throwable) + cache[url]?.let { + onReady(it) + return + } + + val state = UrlPreviewState.Error(throwable.message ?: "Error Loading url preview") + cache.put(url, state) + onReady(state) } } ).fetchUrlPreview() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreview.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreview.kt index ec1cc38f5..be0a8d1e4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreview.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreview.kt @@ -8,56 +8,25 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.ui.platform.LocalContext -import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.UrlCachedPreviewer -import com.vitorpamplona.amethyst.service.previews.IUrlPreviewCallback -import com.vitorpamplona.amethyst.service.previews.UrlInfoItem import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @Composable fun UrlPreview(url: String, urlText: String) { - val context = LocalContext.current - var urlPreviewState by remember(url) { - val default = UrlCachedPreviewer.cache[url]?.let { - if (it.allFetchComplete() && it.url == url) { - UrlPreviewState.Loaded(it) - } else { - UrlPreviewState.Empty - } - } ?: UrlPreviewState.Loading - - mutableStateOf(default) + mutableStateOf( + UrlCachedPreviewer.cache.get(url)?.let { it } ?: UrlPreviewState.Loading + ) } // Doesn't use a viewModel because of viewModel reusing issues (too many UrlPreview are created). LaunchedEffect(url) { if (urlPreviewState == UrlPreviewState.Loading) { launch(Dispatchers.IO) { - UrlCachedPreviewer.previewInfo( - url, - object : IUrlPreviewCallback { - override fun onComplete(urlInfo: UrlInfoItem) { - if (urlInfo.allFetchComplete() && urlInfo.url == url) { - urlPreviewState = UrlPreviewState.Loaded(urlInfo) - } else { - urlPreviewState = UrlPreviewState.Empty - } - } - - override fun onFailed(throwable: Throwable) { - urlPreviewState = UrlPreviewState.Error( - context.getString( - R.string.error_parsing_preview_for, - url, - throwable.message - ) - ) - } - } - ) + UrlCachedPreviewer.previewInfo(url) { + urlPreviewState = it + } } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewState.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewState.kt index 585d0d63b..d8035ccf3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewState.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewState.kt @@ -5,8 +5,16 @@ import com.vitorpamplona.amethyst.service.previews.UrlInfoItem @Immutable sealed class UrlPreviewState { + + @Immutable object Loading : UrlPreviewState() + + @Immutable class Loaded(val previewInfo: UrlInfoItem) : UrlPreviewState() + + @Immutable object Empty : UrlPreviewState() + + @Immutable class Error(val errorMessage: String) : UrlPreviewState() }