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

View file

@ -1,16 +1,21 @@
package com.pixelized.biblib.ui.composable.items package com.pixelized.biblib.ui.composable.items
import androidx.compose.animation.Crossfade import androidx.compose.animation.Crossfade
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.DefaultAlpha 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.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale 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 import java.net.URL
@Composable @Composable
@ -26,7 +31,8 @@ fun Image(
alpha: Float = DefaultAlpha, alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null 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) { Crossfade(modifier = modifier, targetState = cover) {
if (it == placeHolder) { if (it == placeHolder) {
@ -51,3 +57,28 @@ 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.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.util.Log import android.util.Log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.withContext
import kotlinx.coroutines.launch
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.net.URL import java.net.URL
@ -37,15 +35,15 @@ class BitmapCache(context: Context) {
} }
} }
fun download(url: URL, callback: (Bitmap?) -> Unit) { suspend fun download(url: URL, callback: suspend (Bitmap?) -> Unit) {
CoroutineScope(Job() + Dispatchers.IO).launch { val bitmap = withContext(Dispatchers.IO) {
val bitmap = try { try {
BitmapFactory.decodeStream(url.openStream()) BitmapFactory.decodeStream(url.openStream())
} catch (e: IOException) { } catch (e: IOException) {
Log.e("BitmapCache", "BitmapFactory.decodeStream(URL) FAILED !", e) Log.e("BitmapCache", "BitmapFactory.decodeStream(URL) FAILED !", e)
null 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
}