fix: Show previews for playable audio media from accounts (#460)
Previous code showed a generic placeholder for audio media on the account's "Media" tab. Fix this so the preview image is shown (if it's available). - Move the "is this attachment previewable?" code to `Attachment` so it can be reused here. - Restructure the logic in `AccountMediaGridAdapter` to use the new `isPreviewable()` method when deciding whether to show a preview. - Attachments have dedicated placeholder drawables, use those when the preview is not available.
This commit is contained in:
parent
8293e90b73
commit
941f4677eb
|
@ -216,17 +216,6 @@
|
||||||
column="5"/>
|
column="5"/>
|
||||||
</issue>
|
</issue>
|
||||||
|
|
||||||
<issue
|
|
||||||
id="MissingQuantity"
|
|
||||||
message="For locale "ru" (Russian) the following quantities should also be defined: `few` (e.g. "из 2 книг за 2 дня"), `many` (e.g. "из 5 книг за 5 дней"), `one` (e.g. "из 1 книги за 1 день")"
|
|
||||||
errorLine1=" <plurals name="hint_describe_for_visually_impaired">"
|
|
||||||
errorLine2=" ^">
|
|
||||||
<location
|
|
||||||
file="src/main/res/values-ru/strings.xml"
|
|
||||||
line="279"
|
|
||||||
column="5"/>
|
|
||||||
</issue>
|
|
||||||
|
|
||||||
<issue
|
<issue
|
||||||
id="MissingQuantity"
|
id="MissingQuantity"
|
||||||
message="For locale "hi" (Hindi) the following quantity should also be defined: `one` (e.g. "1 घंटा")"
|
message="For locale "hi" (Hindi) the following quantity should also be defined: `one` (e.g. "1 घंटा")"
|
||||||
|
|
|
@ -897,14 +897,14 @@ abstract class StatusBaseViewHolder<T : IStatusViewData> protected constructor(i
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
/**
|
||||||
|
* @return True if all [attachments] are previewable.
|
||||||
|
*
|
||||||
|
* @see Attachment.isPreviewable
|
||||||
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
protected fun hasPreviewableAttachment(attachments: List<Attachment>): Boolean {
|
protected fun hasPreviewableAttachment(attachments: List<Attachment>): Boolean {
|
||||||
for (attachment in attachments) {
|
return attachments.all { it.isPreviewable() }
|
||||||
if (attachment.type == Attachment.Type.UNKNOWN) return false
|
|
||||||
|
|
||||||
if (attachment.meta?.original?.width == null && attachment.meta?.small?.width == null) return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getReblogDescription(context: Context, status: IStatusViewData): CharSequence {
|
private fun getReblogDescription(context: Context, status: IStatusViewData): CharSequence {
|
||||||
|
|
|
@ -7,19 +7,18 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
import androidx.core.view.setPadding
|
|
||||||
import androidx.paging.PagingDataAdapter
|
import androidx.paging.PagingDataAdapter
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import app.pachli.R
|
import app.pachli.R
|
||||||
|
import app.pachli.adapter.isPlayable
|
||||||
import app.pachli.core.activity.decodeBlurHash
|
import app.pachli.core.activity.decodeBlurHash
|
||||||
import app.pachli.core.common.extensions.hide
|
|
||||||
import app.pachli.core.common.extensions.show
|
import app.pachli.core.common.extensions.show
|
||||||
import app.pachli.core.designsystem.R as DR
|
import app.pachli.core.common.extensions.visible
|
||||||
import app.pachli.core.navigation.AttachmentViewData
|
import app.pachli.core.navigation.AttachmentViewData
|
||||||
import app.pachli.core.network.model.Attachment
|
|
||||||
import app.pachli.databinding.ItemAccountMediaBinding
|
import app.pachli.databinding.ItemAccountMediaBinding
|
||||||
import app.pachli.util.BindingHolder
|
import app.pachli.util.BindingHolder
|
||||||
import app.pachli.util.getFormattedDescription
|
import app.pachli.util.getFormattedDescription
|
||||||
|
import app.pachli.util.iconResource
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.google.android.material.color.MaterialColors
|
import com.google.android.material.color.MaterialColors
|
||||||
import java.util.Random
|
import java.util.Random
|
||||||
|
@ -41,7 +40,7 @@ class AccountMediaGridAdapter(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val baseItemBackgroundColor = MaterialColors.getColor(context, com.google.android.material.R.attr.colorSurface, Color.BLACK)
|
private val baseItemBackgroundColor = MaterialColors.getColor(context, com.google.android.material.R.attr.colorSurface, Color.BLACK)
|
||||||
private val videoIndicator = AppCompatResources.getDrawable(context, R.drawable.ic_play_indicator)
|
private val playableIcon = AppCompatResources.getDrawable(context, R.drawable.ic_play_indicator)
|
||||||
private val mediaHiddenDrawable = AppCompatResources.getDrawable(context, R.drawable.ic_hide_media_24dp)
|
private val mediaHiddenDrawable = AppCompatResources.getDrawable(context, R.drawable.ic_hide_media_24dp)
|
||||||
|
|
||||||
private val itemBgBaseHSV = FloatArray(3)
|
private val itemBgBaseHSV = FloatArray(3)
|
||||||
|
@ -57,59 +56,53 @@ class AccountMediaGridAdapter(
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: BindingHolder<ItemAccountMediaBinding>, position: Int) {
|
override fun onBindViewHolder(holder: BindingHolder<ItemAccountMediaBinding>, position: Int) {
|
||||||
val context = holder.binding.root.context
|
val context = holder.binding.root.context
|
||||||
getItem(position)?.let { item ->
|
|
||||||
|
|
||||||
|
getItem(position)?.let { item ->
|
||||||
val imageView = holder.binding.accountMediaImageView
|
val imageView = holder.binding.accountMediaImageView
|
||||||
val overlay = holder.binding.accountMediaImageViewOverlay
|
val overlay = holder.binding.accountMediaImageViewOverlay
|
||||||
|
|
||||||
val blurhash = item.attachment.blurhash
|
val placeholder = item.attachment.blurhash?.let {
|
||||||
val placeholder = if (useBlurhash && blurhash != null) {
|
if (useBlurhash) decodeBlurHash(context, it) else null
|
||||||
decodeBlurHash(context, blurhash)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.attachment.type == Attachment.Type.AUDIO) {
|
when {
|
||||||
overlay.hide()
|
item.sensitive && !item.isRevealed -> {
|
||||||
|
|
||||||
imageView.setPadding(context.resources.getDimensionPixelSize(DR.dimen.profile_media_audio_icon_padding))
|
|
||||||
|
|
||||||
Glide.with(imageView)
|
|
||||||
.load(R.drawable.ic_music_box_preview_24dp)
|
|
||||||
.centerInside()
|
|
||||||
.into(imageView)
|
|
||||||
|
|
||||||
imageView.contentDescription = item.attachment.getFormattedDescription(context)
|
|
||||||
} else if (item.sensitive && !item.isRevealed) {
|
|
||||||
overlay.show()
|
|
||||||
overlay.setImageDrawable(mediaHiddenDrawable)
|
|
||||||
|
|
||||||
imageView.setPadding(0)
|
|
||||||
|
|
||||||
Glide.with(imageView)
|
|
||||||
.load(placeholder)
|
|
||||||
.centerInside()
|
|
||||||
.into(imageView)
|
|
||||||
|
|
||||||
imageView.contentDescription = imageView.context.getString(R.string.post_media_hidden_title)
|
|
||||||
} else {
|
|
||||||
if (item.attachment.type == Attachment.Type.VIDEO || item.attachment.type == Attachment.Type.GIFV) {
|
|
||||||
overlay.show()
|
overlay.show()
|
||||||
overlay.setImageDrawable(videoIndicator)
|
overlay.setImageDrawable(mediaHiddenDrawable)
|
||||||
} else {
|
|
||||||
overlay.hide()
|
Glide.with(imageView)
|
||||||
|
.load(placeholder)
|
||||||
|
.centerInside()
|
||||||
|
.into(imageView)
|
||||||
|
|
||||||
|
imageView.contentDescription = context.getString(R.string.post_media_hidden_title)
|
||||||
}
|
}
|
||||||
|
|
||||||
imageView.setPadding(0)
|
item.attachment.isPreviewable() -> {
|
||||||
|
if (item.attachment.type.isPlayable()) overlay.setImageDrawable(playableIcon)
|
||||||
|
overlay.visible(item.attachment.type.isPlayable())
|
||||||
|
|
||||||
Glide.with(imageView)
|
Glide.with(imageView)
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
.load(item.attachment.previewUrl)
|
.load(item.attachment.previewUrl)
|
||||||
.placeholder(placeholder)
|
.placeholder(placeholder)
|
||||||
.centerInside()
|
.centerInside()
|
||||||
.into(imageView)
|
.into(imageView)
|
||||||
|
|
||||||
imageView.contentDescription = item.attachment.getFormattedDescription(context)
|
imageView.contentDescription = item.attachment.getFormattedDescription(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
if (item.attachment.type.isPlayable()) overlay.setImageDrawable(playableIcon)
|
||||||
|
overlay.visible(item.attachment.type.isPlayable())
|
||||||
|
|
||||||
|
Glide.with(imageView)
|
||||||
|
.load(item.attachment.iconResource())
|
||||||
|
.centerInside()
|
||||||
|
.into(imageView)
|
||||||
|
|
||||||
|
imageView.contentDescription = item.attachment.getFormattedDescription(context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.binding.root.setOnClickListener {
|
holder.binding.root.setOnClickListener {
|
||||||
|
@ -118,7 +111,7 @@ class AccountMediaGridAdapter(
|
||||||
|
|
||||||
holder.binding.root.setOnLongClickListener { view ->
|
holder.binding.root.setOnLongClickListener { view ->
|
||||||
val description = item.attachment.getFormattedDescription(view.context)
|
val description = item.attachment.getFormattedDescription(view.context)
|
||||||
Toast.makeText(view.context, description, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, description, Toast.LENGTH_LONG).show()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,8 +63,6 @@
|
||||||
|
|
||||||
<dimen name="profile_media_spacing">3dp</dimen>
|
<dimen name="profile_media_spacing">3dp</dimen>
|
||||||
|
|
||||||
<dimen name="profile_media_audio_icon_padding">16dp</dimen>
|
|
||||||
|
|
||||||
<dimen name="preview_image_spacing">4dp</dimen>
|
<dimen name="preview_image_spacing">4dp</dimen>
|
||||||
|
|
||||||
<dimen name="graph_line_thickness">1dp</dimen>
|
<dimen name="graph_line_thickness">1dp</dimen>
|
||||||
|
|
|
@ -103,4 +103,13 @@ data class Attachment(
|
||||||
return (width / height).toDouble()
|
return (width / height).toDouble()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True if this attachment can be previewed. A previewable attachment
|
||||||
|
* must be a known type and have a non-null width for the preview image.
|
||||||
|
*/
|
||||||
|
fun isPreviewable(): Boolean {
|
||||||
|
if (type == Type.UNKNOWN) return false
|
||||||
|
return !(meta?.original?.width == null && meta?.small?.width == null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue