Image Loading Sent to Background for smooth UI

This commit is contained in:
shabinder 2021-04-15 00:06:51 +05:30
parent c25837845e
commit c9696fa4aa
4 changed files with 84 additions and 90 deletions

View File

@ -98,9 +98,6 @@ class MainActivity : ComponentActivity(), PaymentResultListener {
permissionGranted = remember { mutableStateOf(true) }
val view = LocalView.current
LaunchedEffect(view) {
permissionGranted.value = checkPermissions()
}
Box {
root = SpotiFlyerRootContent(
rememberRootComponent(::spotiFlyerRoot),
@ -114,6 +111,9 @@ class MainActivity : ComponentActivity(), PaymentResultListener {
)
}
LaunchedEffect(view) {
permissionGranted.value = checkPermissions()
}
NetworkDialog()
PermissionDialog()
}

View File

@ -27,10 +27,7 @@ import com.mpatric.mp3agic.Mp3File
import com.shabinder.common.database.appContext
import com.shabinder.common.models.TrackDetails
import com.shabinder.database.Database
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.*
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
@ -76,6 +73,7 @@ actual class Dir actual constructor(
}
actual suspend fun cacheImage(image: Any, path: String) {
withContext(Dispatchers.IO){
try {
FileOutputStream(path).use { out ->
(image as? Bitmap)?.compress(Bitmap.CompressFormat.JPEG, 100, out)
@ -84,12 +82,14 @@ actual class Dir actual constructor(
e.printStackTrace()
}
}
}
@Suppress("BlockingMethodInNonBlockingContext")
actual suspend fun saveFileWithMetadata(
mp3ByteArray: ByteArray,
trackDetails: TrackDetails
) {
withContext(Dispatchers.IO){
val songFile = File(trackDetails.outputFilePath)
/*
* Check , if Fetch was Used, File is saved Already, else write byteArray we Received
@ -140,6 +140,7 @@ actual class Dir actual constructor(
}
}
}
}
actual fun addToLibrary(path: String) {
logger.d { "Scanning File" }
@ -149,9 +150,9 @@ actual class Dir actual constructor(
)
}
actual suspend fun loadImage(url: String): Picture {
actual suspend fun loadImage(url: String): Picture = withContext(Dispatchers.IO){
val cachePath = imageCacheDir() + getNameURL(url)
return Picture(image = (loadCachedImage(cachePath) ?: freshImage(url))?.asImageBitmap())
Picture(image = (loadCachedImage(cachePath) ?: freshImage(url))?.asImageBitmap())
}
private fun loadCachedImage(cachePath: String): Bitmap? {
@ -162,8 +163,9 @@ actual class Dir actual constructor(
null
}
}
private suspend fun freshImage(url: String): Bitmap? {
return try {
private suspend fun freshImage(url: String): Bitmap? = withContext(Dispatchers.IO) {
try {
val source = URL(url)
val connection: HttpURLConnection = source.openConnection() as HttpURLConnection
connection.connectTimeout = 5000

View File

@ -42,17 +42,15 @@ actual class YoutubeProvider actual constructor(
private val sampleDomain2 = "youtube.com"
private val sampleDomain3 = "youtu.be"
actual suspend fun query(fullLink: String): PlatformQueryResult? {
actual suspend fun query(fullLink: String): PlatformQueryResult? = withContext(Dispatchers.IO) {
val link = fullLink.removePrefix("https://").removePrefix("http://")
if (link.contains("playlist", true) || link.contains("list", true)) {
// Given Link is of a Playlist
logger.i { link }
val playlistId = link.substringAfter("?list=").substringAfter("&list=").substringBefore("&").substringBefore("?")
return withContext(Dispatchers.IO) {
getYTPlaylist(
playlistId
)
}
} else { // Given Link is of a Video
var searchId = "error"
when {
@ -66,12 +64,10 @@ actual class YoutubeProvider actual constructor(
searchId = link.substringAfterLast("/", "error").substringBefore("&")
}
}
return if (searchId != "error") {
withContext(Dispatchers.IO) {
if (searchId != "error") {
getYTTrack(
searchId
)
}
} else {
logger.d { "Your Youtube Link is not of a Video!!" }
null
@ -81,7 +77,7 @@ actual class YoutubeProvider actual constructor(
private suspend fun getYTPlaylist(
searchId: String
): PlatformQueryResult? {
): PlatformQueryResult? = withContext(Dispatchers.IO) {
val result = PlatformQueryResult(
folderType = "",
subFolder = "",
@ -133,14 +129,13 @@ actual class YoutubeProvider actual constructor(
logger.d { "An Error Occurred While Processing!" }
}
}
return if (result.title.isNotBlank()) result
else null
if (result.title.isNotBlank()) result else null
}
@Suppress("DefaultLocale")
private suspend fun getYTTrack(
searchId: String,
): PlatformQueryResult? {
): PlatformQueryResult? = withContext(Dispatchers.IO) {
val result = PlatformQueryResult(
folderType = "",
subFolder = "",
@ -188,7 +183,6 @@ actual class YoutubeProvider actual constructor(
logger.e { "An Error Occurred While Processing!,$searchId" }
}
}
return if (result.title.isNotBlank()) result
else null
if (result.title.isNotBlank()) result else null
}
}

View File

@ -173,7 +173,7 @@ class ForegroundService : Service(), CoroutineScope {
**/
private fun downloadAllTracks(trackList: List<TrackDetails>) {
trackList.forEach {
launch {
launch(Dispatchers.IO) {
if (!it.videoID.isNullOrBlank()) { // Video ID already known!
downloadTrack(it.videoID!!, it)
} else {
@ -193,8 +193,7 @@ class ForegroundService : Service(), CoroutineScope {
}
}
private fun downloadTrack(videoID: String, track: TrackDetails) {
launch {
private suspend fun downloadTrack(videoID: String, track: TrackDetails) {
try {
val url = fetcher.youtubeMp3.getMp3DownloadLink(videoID)
if (url == null) {
@ -208,7 +207,6 @@ class ForegroundService : Service(), CoroutineScope {
allTracksStatus[track.title] = DownloadStatus.Failed
}
}
}
private fun enqueueDownload(url: String, track: TrackDetails) {
val request = Request(url, track.outputFilePath).apply {