issue 2890: Add an "ALT" sticker to the media preview container (#2942)

* issue 2890: Add an "ALT" sticker to the media preview container if there are descriptions

* issue 2890: Use end and start for positioning

* issue 2890: Adapt to new media view group

* issue 2890: Use an indicator overlay for every (single) preview image

* issue 2890: Reduce radius to match that of the preview layout

* issue 2890: Remove (again) unused code

* issue 2890: Set visibility in any case

* issue 2890: Use a translatable text for ALT

* issue 2890: Show ALT flag only when showing media

* issue 2890: Call doOnLayout on the layout wrapper
This commit is contained in:
UlrichKu 2022-12-18 16:50:30 +01:00 committed by GitHub
parent 2de2af0a8c
commit 6aed1c6806
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 66 additions and 13 deletions

View file

@ -411,14 +411,15 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
return ImageLoadingHelper.decodeBlurHash(this.avatar.getContext(), blurhash); return ImageLoadingHelper.decodeBlurHash(this.avatar.getContext(), blurhash);
} }
private void loadImage(MediaPreviewImageView imageView, private void loadImage(View wrapper,
MediaPreviewImageView imageView,
@Nullable String previewUrl, @Nullable String previewUrl,
@Nullable MetaData meta, @Nullable MetaData meta,
@Nullable String blurhash) { @Nullable String blurhash) {
Drawable placeholder = blurhash != null ? decodeBlurHash(blurhash) : mediaPreviewUnloaded; Drawable placeholder = blurhash != null ? decodeBlurHash(blurhash) : mediaPreviewUnloaded;
ViewKt.doOnLayout(imageView, view -> { ViewKt.doOnLayout(wrapper, view -> {
if (TextUtils.isEmpty(previewUrl)) { if (TextUtils.isEmpty(previewUrl)) {
imageView.removeFocalPoint(); imageView.removeFocalPoint();
@ -433,7 +434,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
if (focus != null) { // If there is a focal point for this attachment: if (focus != null) { // If there is a focal point for this attachment:
imageView.setFocalPoint(focus); imageView.setFocalPoint(focus);
Glide.with(imageView) Glide.with(imageView.getContext())
.load(previewUrl) .load(previewUrl)
.placeholder(placeholder) .placeholder(placeholder)
.centerInside() .centerInside()
@ -460,19 +461,21 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
mediaPreview.setVisibility(View.VISIBLE); mediaPreview.setVisibility(View.VISIBLE);
mediaPreview.setAspectRatios(AttachmentHelper.aspectRatios(attachments)); mediaPreview.setAspectRatios(AttachmentHelper.aspectRatios(attachments));
mediaPreview.forEachIndexed((i, imageView) -> { mediaPreview.forEachIndexed((i, wrapper, imageView, descriptionIndicator) -> {
Attachment attachment = attachments.get(i); Attachment attachment = attachments.get(i);
String previewUrl = attachment.getPreviewUrl(); String previewUrl = attachment.getPreviewUrl();
String description = attachment.getDescription(); String description = attachment.getDescription();
boolean hasDescription = !TextUtils.isEmpty(description);
if (TextUtils.isEmpty(description)) { if (hasDescription) {
imageView.setContentDescription(imageView.getContext()
.getString(R.string.action_view_media));
} else {
imageView.setContentDescription(description); imageView.setContentDescription(description);
} else {
imageView.setContentDescription(imageView.getContext().getString(R.string.action_view_media));
} }
descriptionIndicator.setVisibility(hasDescription ? View.VISIBLE : View.GONE);
loadImage( loadImage(
wrapper,
imageView, imageView,
showingContent ? previewUrl : null, showingContent ? previewUrl : null,
attachment.getMeta(), attachment.getMeta(),
@ -502,6 +505,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
} }
v.setVisibility(View.GONE); v.setVisibility(View.GONE);
sensitiveMediaWarning.setVisibility(View.VISIBLE); sensitiveMediaWarning.setVisibility(View.VISIBLE);
descriptionIndicator.setVisibility(View.GONE);
}); });
sensitiveMediaWarning.setOnClickListener(v -> { sensitiveMediaWarning.setOnClickListener(v -> {
if (getBindingAdapterPosition() != RecyclerView.NO_POSITION) { if (getBindingAdapterPosition() != RecyclerView.NO_POSITION) {
@ -509,6 +513,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
} }
v.setVisibility(View.GONE); v.setVisibility(View.GONE);
sensitiveMediaShow.setVisibility(View.VISIBLE); sensitiveMediaShow.setVisibility(View.VISIBLE);
descriptionIndicator.setVisibility(hasDescription ? View.VISIBLE : View.GONE);
}); });
return null; return null;

View file

@ -2,9 +2,11 @@ package com.keylesspalace.tusky.view
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView
import com.keylesspalace.tusky.R import com.keylesspalace.tusky.R
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -26,7 +28,9 @@ class MediaPreviewLayout(context: Context, attrs: AttributeSet? = null) :
attachImageViews() attachImageViews()
} }
private val imageViewCache = Array(4) { MediaPreviewImageView(context) } private val imageViewCache = Array(4) {
LayoutInflater.from(context).inflate(R.layout.item_image_preview_overlay, this, false)
}
private var measuredOrientation = LinearLayout.VERTICAL private var measuredOrientation = LinearLayout.VERTICAL
@ -180,9 +184,15 @@ class MediaPreviewLayout(context: Context, attrs: AttributeSet? = null) :
} }
} }
inline fun forEachIndexed(action: (Int, MediaPreviewImageView) -> Unit) { inline fun forEachIndexed(action: (Int, View, MediaPreviewImageView, TextView) -> Unit) {
for (index in 0 until childCount) { for (index in 0 until childCount) {
action(index, getChildAt(index) as MediaPreviewImageView) val wrapper = getChildAt(index)
action(
index,
wrapper,
wrapper.findViewById(R.id.preview_image_view) as MediaPreviewImageView,
wrapper.findViewById(R.id.preview_media_description_indicator) as TextView
)
} }
} }
} }

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="8dp" /> <corners android:radius="7dp" />
<solid android:color="@color/color_background_transparent_60" /> <solid android:color="@color/color_background_transparent_60" />
</shape> </shape>

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.keylesspalace.tusky.view.MediaPreviewImageView
android:id="@+id/preview_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAccessibility="no"
tools:ignore="RtlSymmetry"
tools:visibility="visible" />
<TextView
android:id="@+id/preview_media_description_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary"
android:textSize="?attr/status_text_small"
android:background="@drawable/media_warning_bg"
android:contentDescription="@null"
android:paddingLeft="5dp"
android:paddingTop="3dp"
android:paddingRight="5dp"
android:paddingBottom="3dp"
android:layout_margin="3dp"
android:visibility="gone"
android:text="@string/post_media_alt"
app:layout_constraintEnd_toEndOf="@+id/preview_image_view"
app:layout_constraintBottom_toBottomOf="@+id/preview_image_view"
app:tint="@color/white" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -20,7 +20,7 @@
android:contentDescription="@null" android:contentDescription="@null"
android:padding="@dimen/status_sensitive_media_button_padding" android:padding="@dimen/status_sensitive_media_button_padding"
android:visibility="gone" android:visibility="gone"
app:layout_constraintLeft_toLeftOf="@+id/status_media_preview_container" app:layout_constraintStart_toStartOf="@+id/status_media_preview_container"
app:layout_constraintTop_toTopOf="@+id/status_media_preview_container" app:layout_constraintTop_toTopOf="@+id/status_media_preview_container"
app:srcCompat="@drawable/ic_eye_24dp" app:srcCompat="@drawable/ic_eye_24dp"
app:tint="@color/white" /> app:tint="@color/white" />

View file

@ -40,6 +40,7 @@
<string name="post_boosted_format">%s teilte</string> <string name="post_boosted_format">%s teilte</string>
<string name="post_sensitive_media_title">Heikle Inhalte</string> <string name="post_sensitive_media_title">Heikle Inhalte</string>
<string name="post_media_hidden_title">Medien versteckt</string> <string name="post_media_hidden_title">Medien versteckt</string>
<string name="post_media_alt">ALT</string>
<string name="post_sensitive_media_directions">Zum Anzeigen tippen</string> <string name="post_sensitive_media_directions">Zum Anzeigen tippen</string>
<string name="post_content_warning_show_more">Zeige mehr</string> <string name="post_content_warning_show_more">Zeige mehr</string>
<string name="post_content_warning_show_less">Zeige weniger</string> <string name="post_content_warning_show_less">Zeige weniger</string>

View file

@ -60,6 +60,7 @@
<string name="post_boosted_format">%s boosted</string> <string name="post_boosted_format">%s boosted</string>
<string name="post_sensitive_media_title">Sensitive content</string> <string name="post_sensitive_media_title">Sensitive content</string>
<string name="post_media_hidden_title">Media hidden</string> <string name="post_media_hidden_title">Media hidden</string>
<string name="post_media_alt">ALT</string>
<string name="post_sensitive_media_directions">Click to view</string> <string name="post_sensitive_media_directions">Click to view</string>
<string name="post_content_warning_show_more">Show More</string> <string name="post_content_warning_show_more">Show More</string>
<string name="post_content_warning_show_less">Show Less</string> <string name="post_content_warning_show_less">Show Less</string>