Fix two bugs in the new image loader:

1. Id was checked for nullability, but it is actually an empty string in most cases where there is no Cover art.
This lead to queries without id set.
2. Size was not respected by the new image loader.
This commit is contained in:
tzugen 2021-06-02 15:21:45 +02:00
parent 90ecbe4b78
commit 2eaa9a2091
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
4 changed files with 49 additions and 16 deletions

View File

@ -22,8 +22,9 @@ class CoverArtRequestHandler(private val apiClient: SubsonicAPIClient) : Request
override fun load(request: Request, networkPolicy: Int): Result {
val id = request.uri.getQueryParameter(QUERY_ID)
?: throw IllegalArgumentException("Nullable id")
val size = request.uri.getQueryParameter(SIZE)?.toLong()
val response = apiClient.getCoverArt(id)
val response = apiClient.getCoverArt(id, size)
if (response.hasError() || response.stream == null) {
throw IOException("${response.apiError}")
} else {

View File

@ -7,16 +7,24 @@ internal const val AUTHORITY = BuildConfig.LIBRARY_PACKAGE_NAME
internal const val COVER_ART_PATH = "cover_art"
internal const val AVATAR_PATH = "avatar"
internal const val QUERY_ID = "id"
internal const val SIZE = "size"
internal const val QUERY_USERNAME = "username"
internal fun createLoadCoverArtRequest(entityId: String): Uri = Uri.Builder()
/**
* Picasso.load() only accepts an URI as parameter. Therefore we create a bogus URI, in which
* we encode the data that we need in the RequestHandler.
*/
internal fun createLoadCoverArtRequest(config: ImageRequest.CoverArt): Uri =
Uri.Builder()
.scheme(SCHEME)
.authority(AUTHORITY)
.appendPath(COVER_ART_PATH)
.appendQueryParameter(QUERY_ID, entityId)
.appendQueryParameter(QUERY_ID, config.entityId)
.appendQueryParameter(SIZE, config.size.toString())
.build()
internal fun createLoadAvatarRequest(username: String): Uri = Uri.Builder()
internal fun createLoadAvatarRequest(username: String): Uri =
Uri.Builder()
.scheme(SCHEME)
.authority(AUTHORITY)
.appendPath(AVATAR_PATH)

View File

@ -6,6 +6,9 @@ import com.squareup.picasso.Picasso
import com.squareup.picasso.RequestCreator
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
// TODO: Caching doesn't work as expected because our query string varies.
// Need to use .stableKey() method
class SubsonicImageLoader(
context: Context,
apiClient: SubsonicAPIClient
@ -13,7 +16,7 @@ class SubsonicImageLoader(
private val picasso = Picasso.Builder(context)
.addRequestHandler(CoverArtRequestHandler(apiClient))
.addRequestHandler(AvatarRequestHandler(apiClient))
.build().apply { setIndicatorsEnabled(BuildConfig.DEBUG) }
.build().apply { setIndicatorsEnabled(true) }
fun load(request: ImageRequest) = when (request) {
is ImageRequest.CoverArt -> loadCoverArt(request)
@ -21,9 +24,10 @@ class SubsonicImageLoader(
}
private fun loadCoverArt(request: ImageRequest.CoverArt) {
picasso.load(createLoadCoverArtRequest(request.entityId))
picasso.load(createLoadCoverArtRequest(request))
.addPlaceholder(request)
.addError(request)
.stableKey("${request.entityId}-${request.size}" )
.into(request.imageView)
}
@ -31,6 +35,7 @@ class SubsonicImageLoader(
picasso.load(createLoadAvatarRequest(request.username))
.addPlaceholder(request)
.addError(request)
.stableKey(request.username)
.into(request.imageView)
}
@ -59,8 +64,9 @@ sealed class ImageRequest(
class CoverArt(
val entityId: String,
imageView: ImageView,
val size: Int,
placeHolderDrawableRes: Int? = null,
errorDrawableRes: Int? = null
errorDrawableRes: Int? = null,
) : ImageRequest(
placeHolderDrawableRes,
errorDrawableRes,

View File

@ -2,12 +2,15 @@ package org.moire.ultrasonic.subsonic
import android.view.View
import android.widget.ImageView
import androidx.core.content.res.ResourcesCompat
import org.moire.ultrasonic.R
import org.moire.ultrasonic.app.UApp
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.subsonic.loader.image.ImageRequest
import org.moire.ultrasonic.subsonic.loader.image.SubsonicImageLoader
import org.moire.ultrasonic.util.ImageLoader
import org.moire.ultrasonic.util.LegacyImageLoader
import org.moire.ultrasonic.util.Util
/**
* Temporary proxy between new [SubsonicImageLoader] and [ImageLoader] interface and old
@ -19,6 +22,11 @@ class SubsonicImageLoaderProxy(
legacyImageLoader: LegacyImageLoader,
private val subsonicImageLoader: SubsonicImageLoader
) : ImageLoader by legacyImageLoader {
private var imageSizeLarge = Util.getMaxDisplayMetric()
private var imageSizeDefault = 0
override fun loadImage(
view: View?,
entry: MusicDirectory.Entry?,
@ -40,16 +48,18 @@ class SubsonicImageLoaderProxy(
defaultResourceId: Int
) {
val id = entry?.coverArt
var requestedSize = size
val unknownImageId =
if (defaultResourceId == -1) R.drawable.unknown_album
else defaultResourceId
if (id != null &&
view != null &&
view is ImageView
) {
if (requestedSize <= 0) {
requestedSize = if (large) imageSizeLarge else imageSizeDefault
}
if (id != null && id.isNotEmpty() && view is ImageView) {
val request = ImageRequest.CoverArt(
id, view,
id, view, requestedSize,
placeHolderDrawableRes = unknownImageId,
errorDrawableRes = unknownImageId
)
@ -65,10 +75,7 @@ class SubsonicImageLoaderProxy(
crossFade: Boolean,
highQuality: Boolean
) {
if (username != null &&
view != null &&
view is ImageView
) {
if (username != null && username.isNotEmpty() && view is ImageView) {
val request = ImageRequest.Avatar(
username, view,
placeHolderDrawableRes = R.drawable.ic_contact_picture,
@ -77,4 +84,15 @@ class SubsonicImageLoaderProxy(
subsonicImageLoader.load(request)
}
}
init {
val default = ResourcesCompat.getDrawable(
UApp.applicationContext().resources, R.drawable.unknown_album, null)
// Determine the density-dependent image sizes by taking the fallback album
// image and querying its size.
if (default != null) {
imageSizeDefault = default.intrinsicHeight
}
}
}