Moves URL Previews into suspend functions
This commit is contained in:
@@ -2,33 +2,35 @@ package com.vitorpamplona.amethyst.model
|
|||||||
|
|
||||||
import android.util.LruCache
|
import android.util.LruCache
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
|
||||||
import com.vitorpamplona.amethyst.service.previews.BahaUrlPreview
|
import com.vitorpamplona.amethyst.service.previews.BahaUrlPreview
|
||||||
import com.vitorpamplona.amethyst.service.previews.IUrlPreviewCallback
|
import com.vitorpamplona.amethyst.service.previews.IUrlPreviewCallback
|
||||||
import com.vitorpamplona.amethyst.service.previews.UrlInfoItem
|
import com.vitorpamplona.amethyst.service.previews.UrlInfoItem
|
||||||
import com.vitorpamplona.amethyst.ui.components.UrlPreviewState
|
import com.vitorpamplona.amethyst.ui.components.UrlPreviewState
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
object UrlCachedPreviewer {
|
object UrlCachedPreviewer {
|
||||||
var cache = LruCache<String, UrlPreviewState>(100)
|
var cache = LruCache<String, UrlPreviewState>(100)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
fun previewInfo(url: String, onReady: (UrlPreviewState) -> Unit) {
|
suspend fun previewInfo(
|
||||||
checkNotInMainThread()
|
url: String,
|
||||||
|
onReady: suspend (UrlPreviewState) -> Unit
|
||||||
|
) = withContext(Dispatchers.IO) {
|
||||||
cache[url]?.let {
|
cache[url]?.let {
|
||||||
onReady(it)
|
onReady(it)
|
||||||
return
|
return@withContext
|
||||||
}
|
}
|
||||||
|
|
||||||
BahaUrlPreview(
|
BahaUrlPreview(
|
||||||
url,
|
url,
|
||||||
object : IUrlPreviewCallback {
|
object : IUrlPreviewCallback {
|
||||||
override fun onComplete(urlInfo: UrlInfoItem) {
|
override suspend fun onComplete(urlInfo: UrlInfoItem) = withContext(Dispatchers.IO) {
|
||||||
cache[url]?.let {
|
cache[url]?.let {
|
||||||
if (it is UrlPreviewState.Loaded || it is UrlPreviewState.Empty) {
|
if (it is UrlPreviewState.Loaded || it is UrlPreviewState.Empty) {
|
||||||
onReady(it)
|
onReady(it)
|
||||||
return
|
return@withContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,10 +44,10 @@ object UrlCachedPreviewer {
|
|||||||
onReady(state)
|
onReady(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailed(throwable: Throwable) {
|
override suspend fun onFailed(throwable: Throwable) = withContext(Dispatchers.IO) {
|
||||||
cache[url]?.let {
|
cache[url]?.let {
|
||||||
onReady(it)
|
onReady(it)
|
||||||
return
|
return@withContext
|
||||||
}
|
}
|
||||||
|
|
||||||
val state = UrlPreviewState.Error(throwable.message ?: "Error Loading url preview")
|
val state = UrlPreviewState.Error(throwable.message ?: "Error Loading url preview")
|
||||||
|
|||||||
@@ -1,25 +1,21 @@
|
|||||||
package com.vitorpamplona.amethyst.service.previews
|
package com.vitorpamplona.amethyst.service.previews
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class BahaUrlPreview(val url: String, var callback: IUrlPreviewCallback?) {
|
class BahaUrlPreview(val url: String, var callback: IUrlPreviewCallback?) {
|
||||||
val scope = CoroutineScope(Job() + Dispatchers.IO)
|
|
||||||
private val imageExtensionArray = arrayOf(".gif", ".png", ".jpg", ".jpeg", ".bmp", ".webp")
|
private val imageExtensionArray = arrayOf(".gif", ".png", ".jpg", ".jpeg", ".bmp", ".webp")
|
||||||
|
|
||||||
fun fetchUrlPreview(timeOut: Int = 30000) {
|
suspend fun fetchUrlPreview(timeOut: Int = 30000) = withContext(Dispatchers.IO) {
|
||||||
val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
|
try {
|
||||||
callback?.onFailed(throwable)
|
|
||||||
}
|
|
||||||
scope.launch(exceptionHandler) {
|
|
||||||
fetch(timeOut)
|
fetch(timeOut)
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
callback?.onFailed(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun fetch(timeOut: Int = 30000) {
|
private suspend fun fetch(timeOut: Int = 30000) {
|
||||||
checkNotInMainThread()
|
|
||||||
lateinit var urlInfoItem: UrlInfoItem
|
lateinit var urlInfoItem: UrlInfoItem
|
||||||
if (checkIsImageUrl()) {
|
if (checkIsImageUrl()) {
|
||||||
urlInfoItem = UrlInfoItem(url = url, image = url)
|
urlInfoItem = UrlInfoItem(url = url, image = url)
|
||||||
@@ -43,7 +39,6 @@ class BahaUrlPreview(val url: String, var callback: IUrlPreviewCallback?) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
scope.cancel()
|
|
||||||
callback = null
|
callback = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
package com.vitorpamplona.amethyst.service.previews
|
package com.vitorpamplona.amethyst.service.previews
|
||||||
|
|
||||||
interface IUrlPreviewCallback {
|
interface IUrlPreviewCallback {
|
||||||
fun onComplete(urlInfo: UrlInfoItem)
|
suspend fun onComplete(urlInfo: UrlInfoItem)
|
||||||
fun onFailed(throwable: Throwable)
|
suspend fun onFailed(throwable: Throwable)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ fun UrlPreview(url: String, urlText: String, accountViewModel: AccountViewModel)
|
|||||||
} else {
|
} else {
|
||||||
var urlPreviewState by remember(url) {
|
var urlPreviewState by remember(url) {
|
||||||
mutableStateOf(
|
mutableStateOf(
|
||||||
UrlCachedPreviewer.cache.get(url)?.let { it } ?: UrlPreviewState.Loading
|
UrlCachedPreviewer.cache.get(url) ?: UrlPreviewState.Loading
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,9 +39,7 @@ fun UrlPreview(url: String, urlText: String, accountViewModel: AccountViewModel)
|
|||||||
LaunchedEffect(url) {
|
LaunchedEffect(url) {
|
||||||
launch(Dispatchers.IO) {
|
launch(Dispatchers.IO) {
|
||||||
UrlCachedPreviewer.previewInfo(url) {
|
UrlCachedPreviewer.previewInfo(url) {
|
||||||
launch(Dispatchers.Main) {
|
urlPreviewState = it
|
||||||
urlPreviewState = it
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user