Rewrite the image download system.

This commit is contained in:
Thomas Andres Gomez 2021-05-19 15:40:13 +02:00
parent 0ce392bba7
commit 9a5cd11782
4 changed files with 44 additions and 39 deletions

View file

@ -1,6 +1,7 @@
package com.pixelized.biblib.ui
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
@ -41,6 +42,8 @@ fun ContentComposable() {
val navigationViewModel = viewModel<NavigationViewModel>()
val main by navigationViewModel.screen.observeAsState()
Log.e("pouet", "Navigation State $main")
Crossfade(targetState = main) {
when (it) {
is Screen.SplashScreen -> SplashScreen()

View file

@ -1,16 +1,21 @@
package com.pixelized.biblib.ui.composable.items
import androidx.compose.animation.Crossfade
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.DefaultAlpha
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import com.pixelized.biblib.utils.extention.toImage
import com.pixelized.biblib.ui.theme.Animation
import com.pixelized.biblib.utils.BitmapCache
import com.pixelized.biblib.utils.injection.get
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.net.URL
@Composable
@ -26,7 +31,8 @@ fun Image(
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null
) {
val cover by remember { contentUrl.toImage(placeHolder) }
val coroutineScope = rememberCoroutineScope()
val cover by remember { download(placeHolder, coroutineScope, contentUrl) }
Crossfade(modifier = modifier, targetState = cover) {
if (it == placeHolder) {
@ -50,4 +56,29 @@ fun Image(
)
}
}
}
private fun download(
placeHolder: Painter,
coroutineScope: CoroutineScope,
url: URL,
): State<Painter> {
val state = mutableStateOf(placeHolder)
coroutineScope.launch {
val cache: BitmapCache = get()
val resource = cache.readFromDisk(url)?.let { BitmapPainter(it.asImageBitmap()) }
if (resource != null) {
state.value = resource
} else {
cache.download(url) { downloaded ->
if (downloaded != null) {
cache.writeToDisk(url, downloaded)
state.value = BitmapPainter(downloaded.asImageBitmap())
}
}
}
}
return state
}

View file

@ -4,10 +4,8 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.io.IOException
import java.net.URL
@ -37,15 +35,15 @@ class BitmapCache(context: Context) {
}
}
fun download(url: URL, callback: (Bitmap?) -> Unit) {
CoroutineScope(Job() + Dispatchers.IO).launch {
val bitmap = try {
suspend fun download(url: URL, callback: suspend (Bitmap?) -> Unit) {
val bitmap = withContext(Dispatchers.IO) {
try {
BitmapFactory.decodeStream(url.openStream())
} catch (e: IOException) {
Log.e("BitmapCache", "BitmapFactory.decodeStream(URL) FAILED !", e)
null
}
callback.invoke(bitmap)
}
callback.invoke(bitmap)
}
}

View file

@ -1,27 +0,0 @@
package com.pixelized.biblib.utils.extention
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
import com.pixelized.biblib.utils.injection.get
import com.pixelized.biblib.utils.BitmapCache
import java.net.URL
fun URL.toImage(placeHolder: Painter): State<Painter> {
val cache: BitmapCache = get()
val resource = cache.readFromDisk(this)?.let { BitmapPainter(it.asImageBitmap()) }
val state = mutableStateOf(resource ?: placeHolder)
if (resource == null) {
cache.download(url = this) { downloaded ->
if (downloaded != null) {
cache.writeToDisk(this, downloaded)
state.value = BitmapPainter(downloaded.asImageBitmap())
}
}
}
return state
}