mirror of
https://github.com/jellyfin/jellyfin-android.git
synced 2026-09-03 05:10:27 +03:00
Download primary images
This commit is contained in:
committed by
Niels van Velzen
parent
641105f08f
commit
ee8ce1607e
@@ -1,6 +1,7 @@
|
||||
package org.jellyfin.mobile.downloads
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.core.net.toUri
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import kotlinx.coroutines.CancellationException
|
||||
@@ -10,8 +11,11 @@ import org.jellyfin.mobile.app.StorageManager
|
||||
import org.jellyfin.mobile.data.dao.DownloadDao
|
||||
import org.jellyfin.mobile.data.entity.DownloadEntity
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.api.client.extensions.imageApi
|
||||
import org.jellyfin.sdk.api.client.extensions.libraryApi
|
||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||
import org.jellyfin.sdk.model.api.ImageFormat
|
||||
import org.jellyfin.sdk.model.api.ImageType
|
||||
|
||||
class DownloadQueue(
|
||||
private val context: Context,
|
||||
@@ -58,9 +62,9 @@ class DownloadQueue(
|
||||
val api = apiClientController.getApiClient(download.serverId, download.userId)
|
||||
|
||||
val storageLocation = storageManager.getStorageLocation()
|
||||
val itemLocation = storageLocation.findFile(download.path) ?: storageLocation.createDirectory(download.path) ?: error("Unable to find or create folder ${download.path}")
|
||||
val itemLocation = storageLocation.findFile(download.path) ?: storageLocation.createDirectory(download.path)
|
||||
?: error("Unable to find or create folder ${download.path}")
|
||||
|
||||
// TODO: Download all mediastreams, thumbnail etc.
|
||||
download(
|
||||
api = api,
|
||||
item = download.item,
|
||||
@@ -84,16 +88,51 @@ class DownloadQueue(
|
||||
itemLocation: DocumentFile,
|
||||
progressCallback: FileDownloader.ProgressCallback,
|
||||
) {
|
||||
val filename = item.path?.replace(Regex("^.*[\\\\/]"), "") ?: error("Missing item path")
|
||||
// Main file
|
||||
download(
|
||||
api = api,
|
||||
itemLocation = itemLocation,
|
||||
fileName = item.path?.replace(Regex("^.*[\\\\/]"), "") ?: error("Missing item path"),
|
||||
uri = api.libraryApi.getDownloadUrl(item.id).toUri(),
|
||||
progressCallback = progressCallback,
|
||||
)
|
||||
|
||||
val fileLocation = itemLocation.findFile(filename) ?: itemLocation.createFile("", filename) ?: error("Unable to find or create file $filename")
|
||||
if (!fileLocation.canRead() || !fileLocation.canWrite()) error("Not allowed to read-write $fileLocation")
|
||||
// Primary image
|
||||
item.imageTags?.get(ImageType.PRIMARY)?.let { imageTag ->
|
||||
download(
|
||||
api = api,
|
||||
itemLocation = itemLocation,
|
||||
fileName = "primary.webp",
|
||||
uri = api.imageApi.getItemImageUrl(
|
||||
itemId = item.id,
|
||||
imageType = ImageType.PRIMARY,
|
||||
tag = imageTag,
|
||||
format = ImageFormat.WEBP
|
||||
).toUri(),
|
||||
progressCallback = progressCallback,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val fileDescriptor = context.contentResolver.openFileDescriptor(fileLocation.uri, "rw") ?: error("Unable to open file descriptor for $fileLocation")
|
||||
private suspend fun download(
|
||||
api: ApiClient,
|
||||
itemLocation: DocumentFile,
|
||||
fileName: String,
|
||||
uri: Uri,
|
||||
progressCallback: FileDownloader.ProgressCallback,
|
||||
) {
|
||||
val documentFile = itemLocation.findFile(fileName)
|
||||
?: itemLocation.createFile("", fileName)
|
||||
?: error("Unable to find or create file $fileName")
|
||||
|
||||
if (!documentFile.canRead() || !documentFile.canWrite()) error("Not allowed to read-write $fileName")
|
||||
|
||||
val fileDescriptor = context.contentResolver.openFileDescriptor(documentFile.uri, "rw")
|
||||
?: error("Unable to open file descriptor for $fileName")
|
||||
|
||||
_downloader.downloadAndSave(
|
||||
api,
|
||||
from = api.libraryApi.getDownloadUrl(item.id).toUri(),
|
||||
api = api,
|
||||
from = uri,
|
||||
to = fileDescriptor,
|
||||
progressCallback = progressCallback,
|
||||
)
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package org.jellyfin.mobile.ui.screens.downloads
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.text.format.Formatter
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.sizeIn
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.AlertDialog
|
||||
@@ -27,7 +29,6 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalResources
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
@@ -43,10 +44,8 @@ import org.jellyfin.mobile.downloads.DownloadStatus
|
||||
import org.jellyfin.mobile.downloads.DownloadsViewModel
|
||||
import org.jellyfin.mobile.utils.lengthRecursive
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.api.client.extensions.imageApi
|
||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||
import org.jellyfin.sdk.model.api.ImageType
|
||||
import org.koin.compose.koinInject
|
||||
|
||||
@Composable
|
||||
@@ -158,21 +157,24 @@ fun DownloadItem(
|
||||
)
|
||||
},
|
||||
icon = {
|
||||
val maxSize = LocalResources.current.getDimensionPixelSize(R.dimen.movie_thumbnail_list_size)
|
||||
val url = remember(apiClient, download.itemId, maxSize) {
|
||||
apiClient.imageApi.getItemImageUrl(
|
||||
itemId = download.itemId,
|
||||
imageType = ImageType.PRIMARY,
|
||||
maxWidth = maxSize,
|
||||
maxHeight = maxSize,
|
||||
)
|
||||
val uri by produceState<Uri?>(initialValue = null, download) {
|
||||
value = withContext(Dispatchers.IO) {
|
||||
storageManager.getStorageLocation()
|
||||
.findFile(download.path)
|
||||
?.findFile("primary.webp")
|
||||
?.uri
|
||||
}
|
||||
}
|
||||
|
||||
AsyncImage(
|
||||
model = url,
|
||||
model = uri,
|
||||
placeholder = painterResource(R.drawable.ic_local_movies_white_64),
|
||||
fallback = painterResource(R.drawable.ic_local_movies_white_64),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.sizeIn(
|
||||
maxWidth = 64.dp,
|
||||
maxHeight = 64.dp,
|
||||
)
|
||||
)
|
||||
},
|
||||
secondaryText = {
|
||||
|
||||
Reference in New Issue
Block a user