Skip to content

Commit

Permalink
fix: Show previews for playable audio media from accounts (#460)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nikclayton authored Feb 20, 2024
1 parent 8293e90 commit 941f467
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 63 deletions.
11 changes: 0 additions & 11 deletions app/lint-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -216,17 +216,6 @@
column="5"/>
</issue>

<issue
id="MissingQuantity"
message="For locale &quot;ru&quot; (Russian) the following quantities should also be defined: `few` (e.g. &quot;из 2 книг за 2 дня&quot;), `many` (e.g. &quot;из 5 книг за 5 дней&quot;), `one` (e.g. &quot;из 1 книги за 1 день&quot;)"
errorLine1=" &lt;plurals name=&quot;hint_describe_for_visually_impaired&quot;>"
errorLine2=" ^">
<location
file="src/main/res/values-ru/strings.xml"
line="279"
column="5"/>
</issue>

<issue
id="MissingQuantity"
message="For locale &quot;hi&quot; (Hindi) the following quantity should also be defined: `one` (e.g. &quot;1 घंटा&quot;)"
Expand Down
12 changes: 6 additions & 6 deletions app/src/main/java/app/pachli/adapter/StatusBaseViewHolder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -897,14 +897,14 @@ abstract class StatusBaseViewHolder<T : IStatusViewData> protected constructor(i
}

companion object {
/**
* @return True if all [attachments] are previewable.
*
* @see Attachment.isPreviewable
*/
@JvmStatic
protected fun hasPreviewableAttachment(attachments: List<Attachment>): Boolean {
for (attachment in attachments) {
if (attachment.type == Attachment.Type.UNKNOWN) return false

if (attachment.meta?.original?.width == null && attachment.meta?.small?.width == null) return false
}
return true
return attachments.all { it.isPreviewable() }
}

private fun getReblogDescription(context: Context, status: IStatusViewData): CharSequence {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,18 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.view.setPadding
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import app.pachli.R
import app.pachli.adapter.isPlayable
import app.pachli.core.activity.decodeBlurHash
import app.pachli.core.common.extensions.hide
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.network.model.Attachment
import app.pachli.databinding.ItemAccountMediaBinding
import app.pachli.util.BindingHolder
import app.pachli.util.getFormattedDescription
import app.pachli.util.iconResource
import com.bumptech.glide.Glide
import com.google.android.material.color.MaterialColors
import java.util.Random
Expand All @@ -41,7 +40,7 @@ class AccountMediaGridAdapter(
) {

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 itemBgBaseHSV = FloatArray(3)
Expand All @@ -57,59 +56,53 @@ class AccountMediaGridAdapter(

override fun onBindViewHolder(holder: BindingHolder<ItemAccountMediaBinding>, position: Int) {
val context = holder.binding.root.context
getItem(position)?.let { item ->

getItem(position)?.let { item ->
val imageView = holder.binding.accountMediaImageView
val overlay = holder.binding.accountMediaImageViewOverlay

val blurhash = item.attachment.blurhash
val placeholder = if (useBlurhash && blurhash != null) {
decodeBlurHash(context, blurhash)
} else {
null
val placeholder = item.attachment.blurhash?.let {
if (useBlurhash) decodeBlurHash(context, it) else null
}

if (item.attachment.type == Attachment.Type.AUDIO) {
overlay.hide()

imageView.setPadding(context.resources.getDimensionPixelSize(DR.dimen.profile_media_audio_icon_padding))
when {
item.sensitive && !item.isRevealed -> {
overlay.show()
overlay.setImageDrawable(mediaHiddenDrawable)

Glide.with(imageView)
.load(R.drawable.ic_music_box_preview_24dp)
.centerInside()
.into(imageView)
Glide.with(imageView)
.load(placeholder)
.centerInside()
.into(imageView)

imageView.contentDescription = item.attachment.getFormattedDescription(context)
} else if (item.sensitive && !item.isRevealed) {
overlay.show()
overlay.setImageDrawable(mediaHiddenDrawable)
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)
.load(placeholder)
.centerInside()
.into(imageView)
Glide.with(imageView)
.asBitmap()
.load(item.attachment.previewUrl)
.placeholder(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.setImageDrawable(videoIndicator)
} else {
overlay.hide()
imageView.contentDescription = item.attachment.getFormattedDescription(context)
}

imageView.setPadding(0)
else -> {
if (item.attachment.type.isPlayable()) overlay.setImageDrawable(playableIcon)
overlay.visible(item.attachment.type.isPlayable())

Glide.with(imageView)
.asBitmap()
.load(item.attachment.previewUrl)
.placeholder(placeholder)
.centerInside()
.into(imageView)
Glide.with(imageView)
.load(item.attachment.iconResource())
.centerInside()
.into(imageView)

imageView.contentDescription = item.attachment.getFormattedDescription(context)
imageView.contentDescription = item.attachment.getFormattedDescription(context)
}
}

holder.binding.root.setOnClickListener {
Expand All @@ -118,7 +111,7 @@ class AccountMediaGridAdapter(

holder.binding.root.setOnLongClickListener { view ->
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
}
}
Expand Down
2 changes: 0 additions & 2 deletions core/designsystem/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@

<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="graph_line_thickness">1dp</dimen>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,13 @@ data class Attachment(
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)
}
}

0 comments on commit 941f467

Please sign in to comment.