mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-04-18 18:17:43 +03:00
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:
parent
90ecbe4b78
commit
2eaa9a2091
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user