add indicator for missing alt texts

closes sk22#355
This commit is contained in:
sk 2023-01-23 19:21:21 +01:00
parent d30b1f7bbd
commit c0c276f03e
10 changed files with 80 additions and 10 deletions

View File

@ -33,6 +33,8 @@ public class GlobalUserPreferences{
public static boolean reduceMotion; public static boolean reduceMotion;
public static boolean keepOnlyLatestNotification; public static boolean keepOnlyLatestNotification;
public static boolean disableAltTextReminder; public static boolean disableAltTextReminder;
public static boolean showAltIndicator;
public static boolean showNoAltIndicator;
public static String publishButtonText; public static String publishButtonText;
public static ThemePreference theme; public static ThemePreference theme;
public static ColorPreference color; public static ColorPreference color;
@ -71,6 +73,8 @@ public class GlobalUserPreferences{
reduceMotion=prefs.getBoolean("reduceMotion", false); reduceMotion=prefs.getBoolean("reduceMotion", false);
keepOnlyLatestNotification=prefs.getBoolean("keepOnlyLatestNotification", false); keepOnlyLatestNotification=prefs.getBoolean("keepOnlyLatestNotification", false);
disableAltTextReminder=prefs.getBoolean("disableAltTextReminder", false); disableAltTextReminder=prefs.getBoolean("disableAltTextReminder", false);
showAltIndicator =prefs.getBoolean("showAltIndicator", true);
showNoAltIndicator =prefs.getBoolean("showNoAltIndicator", true);
publishButtonText=prefs.getString("publishButtonText", ""); publishButtonText=prefs.getString("publishButtonText", "");
theme=ThemePreference.values()[prefs.getInt("theme", 0)]; theme=ThemePreference.values()[prefs.getInt("theme", 0)];
recentLanguages=fromJson(prefs.getString("recentLanguages", null), recentLanguagesType, new HashMap<>()); recentLanguages=fromJson(prefs.getString("recentLanguages", null), recentLanguagesType, new HashMap<>());
@ -102,6 +106,8 @@ public class GlobalUserPreferences{
.putBoolean("reduceMotion", reduceMotion) .putBoolean("reduceMotion", reduceMotion)
.putBoolean("keepOnlyLatestNotification", keepOnlyLatestNotification) .putBoolean("keepOnlyLatestNotification", keepOnlyLatestNotification)
.putBoolean("disableAltTextReminder", disableAltTextReminder) .putBoolean("disableAltTextReminder", disableAltTextReminder)
.putBoolean("showAltIndicator", showAltIndicator)
.putBoolean("showNoAltIndicator", showNoAltIndicator)
.putString("publishButtonText", publishButtonText) .putString("publishButtonText", publishButtonText)
.putInt("theme", theme.ordinal()) .putInt("theme", theme.ordinal())
.putString("color", color.name()) .putString("color", color.name())

View File

@ -163,6 +163,12 @@ public class SettingsFragment extends MastodonToolbarFragment{
GlobalUserPreferences.reduceMotion=i.checked; GlobalUserPreferences.reduceMotion=i.checked;
GlobalUserPreferences.save(); GlobalUserPreferences.save();
})); }));
items.add(new SwitchItem(R.string.sk_settings_show_alt_indicator, R.drawable.ic_fluent_scan_text_24_regular, GlobalUserPreferences.showAltIndicator, i->{
GlobalUserPreferences.showAltIndicator=i.checked;
}));
items.add(new SwitchItem(R.string.sk_settings_show_no_alt_indicator, R.drawable.ic_fluent_important_24_regular, GlobalUserPreferences.showNoAltIndicator, i->{
GlobalUserPreferences.showNoAltIndicator=i.checked;
}));
items.add(new HeaderItem(R.string.settings_behavior)); items.add(new HeaderItem(R.string.settings_behavior));
items.add(new SwitchItem(R.string.settings_gif, R.drawable.ic_fluent_gif_24_regular, GlobalUserPreferences.playGifs, i->{ items.add(new SwitchItem(R.string.settings_gif, R.drawable.ic_fluent_gif_24_regular, GlobalUserPreferences.playGifs, i->{

View File

@ -11,9 +11,11 @@ import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R; import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment; import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.Attachment; import org.joinmastodon.android.model.Attachment;
@ -22,6 +24,7 @@ import org.joinmastodon.android.ui.PhotoLayoutHelper;
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest; import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
import me.grishka.appkit.utils.CubicBezierInterpolator; import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.V;
public class PhotoStatusDisplayItem extends ImageStatusDisplayItem{ public class PhotoStatusDisplayItem extends ImageStatusDisplayItem{
public PhotoStatusDisplayItem(String parentID, Status status, Attachment photo, BaseStatusListFragment parentFragment, int index, int totalPhotos, PhotoLayoutHelper.TiledLayoutResult tiledLayout, PhotoLayoutHelper.TiledLayoutResult.Tile thisTile){ public PhotoStatusDisplayItem(String parentID, Status status, Attachment photo, BaseStatusListFragment parentFragment, int index, int totalPhotos, PhotoLayoutHelper.TiledLayoutResult tiledLayout, PhotoLayoutHelper.TiledLayoutResult.Tile thisTile){
@ -37,10 +40,12 @@ public class PhotoStatusDisplayItem extends ImageStatusDisplayItem{
public static class Holder extends ImageStatusDisplayItem.Holder<PhotoStatusDisplayItem>{ public static class Holder extends ImageStatusDisplayItem.Holder<PhotoStatusDisplayItem>{
private final FrameLayout altTextWrapper; private final FrameLayout altTextWrapper;
private final TextView altTextButton; private final TextView altTextButton;
private final ImageView noAltTextButton;
private final View altTextScroller; private final View altTextScroller;
private final ImageButton altTextClose; private final ImageButton altTextClose;
private final TextView altText; private final TextView altText;
private View altOrNoAltButton;
private boolean altTextShown; private boolean altTextShown;
private AnimatorSet currentAnim; private AnimatorSet currentAnim;
@ -48,11 +53,13 @@ public class PhotoStatusDisplayItem extends ImageStatusDisplayItem{
super(activity, R.layout.display_item_photo, parent); super(activity, R.layout.display_item_photo, parent);
altTextWrapper=findViewById(R.id.alt_text_wrapper); altTextWrapper=findViewById(R.id.alt_text_wrapper);
altTextButton=findViewById(R.id.alt_button); altTextButton=findViewById(R.id.alt_button);
noAltTextButton=findViewById(R.id.no_alt_button);
altTextScroller=findViewById(R.id.alt_text_scroller); altTextScroller=findViewById(R.id.alt_text_scroller);
altTextClose=findViewById(R.id.alt_text_close); altTextClose=findViewById(R.id.alt_text_close);
altText=findViewById(R.id.alt_text); altText=findViewById(R.id.alt_text);
altTextButton.setOnClickListener(this::onShowHideClick); altTextButton.setOnClickListener(this::onShowHideClick);
noAltTextButton.setOnClickListener(this::onShowHideClick);
altTextClose.setOnClickListener(this::onShowHideClick); altTextClose.setOnClickListener(this::onShowHideClick);
// altTextScroller.setNestedScrollingEnabled(true); // altTextScroller.setNestedScrollingEnabled(true);
} }
@ -60,23 +67,46 @@ public class PhotoStatusDisplayItem extends ImageStatusDisplayItem{
@Override @Override
public void onBind(ImageStatusDisplayItem item){ public void onBind(ImageStatusDisplayItem item){
super.onBind(item); super.onBind(item);
boolean altTextMissing = TextUtils.isEmpty(item.attachment.description);
altOrNoAltButton = altTextMissing ? noAltTextButton : altTextButton;
altTextShown=false; altTextShown=false;
if(currentAnim!=null) if(currentAnim!=null)
currentAnim.cancel(); currentAnim.cancel();
altTextScroller.setVisibility(View.GONE); altTextScroller.setVisibility(View.GONE);
altTextClose.setVisibility(View.GONE); altTextClose.setVisibility(View.GONE);
altTextButton.setVisibility(View.VISIBLE); altTextButton.setVisibility(View.VISIBLE);
noAltTextButton.setVisibility(View.VISIBLE);
altTextButton.setAlpha(1f); altTextButton.setAlpha(1f);
if(TextUtils.isEmpty(item.attachment.description)){ noAltTextButton.setAlpha(1f);
altTextWrapper.setVisibility(View.GONE); altTextWrapper.setVisibility(View.VISIBLE);
if (altTextMissing){
if (GlobalUserPreferences.showNoAltIndicator) {
noAltTextButton.setVisibility(View.VISIBLE);
altTextWrapper.setBackgroundResource(R.drawable.bg_image_no_alt_overlay);
altTextButton.setVisibility(View.GONE);
altText.setText(R.string.sk_no_alt_text);
altText.setPadding(V.dp(8), 0, 0, 0);
} else {
altTextWrapper.setVisibility(View.GONE);
}
}else{ }else{
altTextWrapper.setVisibility(View.VISIBLE); if (GlobalUserPreferences.showAltIndicator) {
altText.setText(item.attachment.description); noAltTextButton.setVisibility(View.GONE);
altTextWrapper.setBackgroundResource(R.drawable.bg_image_alt_overlay);
altTextButton.setVisibility(View.VISIBLE);
altTextButton.setText(R.string.sk_alt_button);
altText.setText(item.attachment.description);
altText.setPadding(0, 0, 0, 0);
} else {
altTextWrapper.setVisibility(View.GONE);
}
} }
} }
private void onShowHideClick(View v){ private void onShowHideClick(View v){
boolean show=v.getId()==R.id.alt_button; boolean show=v.getId()==R.id.alt_button || v.getId()==R.id.no_alt_button;
if(altTextShown==show) if(altTextShown==show)
return; return;
@ -88,7 +118,7 @@ public class PhotoStatusDisplayItem extends ImageStatusDisplayItem{
altTextScroller.setVisibility(View.VISIBLE); altTextScroller.setVisibility(View.VISIBLE);
altTextClose.setVisibility(View.VISIBLE); altTextClose.setVisibility(View.VISIBLE);
}else{ }else{
altTextButton.setVisibility(View.VISIBLE); altOrNoAltButton.setVisibility(View.VISIBLE);
// Hide these views temporarily so FrameLayout measures correctly // Hide these views temporarily so FrameLayout measures correctly
altTextScroller.setVisibility(View.GONE); altTextScroller.setVisibility(View.GONE);
altTextClose.setVisibility(View.GONE); altTextClose.setVisibility(View.GONE);
@ -115,7 +145,7 @@ public class PhotoStatusDisplayItem extends ImageStatusDisplayItem{
ObjectAnimator.ofInt(altTextWrapper, "left", prevLeft, altTextWrapper.getLeft()), ObjectAnimator.ofInt(altTextWrapper, "left", prevLeft, altTextWrapper.getLeft()),
ObjectAnimator.ofInt(altTextWrapper, "right", prevRight, altTextWrapper.getRight()), ObjectAnimator.ofInt(altTextWrapper, "right", prevRight, altTextWrapper.getRight()),
ObjectAnimator.ofInt(altTextWrapper, "top", prevTop, altTextWrapper.getTop()), ObjectAnimator.ofInt(altTextWrapper, "top", prevTop, altTextWrapper.getTop()),
ObjectAnimator.ofFloat(altTextButton, View.ALPHA, show ? 1f : 0f, show ? 0f : 1f), ObjectAnimator.ofFloat(altOrNoAltButton, View.ALPHA, show ? 1f : 0f, show ? 0f : 1f),
ObjectAnimator.ofFloat(altTextScroller, View.ALPHA, show ? 0f : 1f, show ? 1f : 0f), ObjectAnimator.ofFloat(altTextScroller, View.ALPHA, show ? 0f : 1f, show ? 1f : 0f),
ObjectAnimator.ofFloat(altTextClose, View.ALPHA, show ? 0f : 1f, show ? 1f : 0f) ObjectAnimator.ofFloat(altTextClose, View.ALPHA, show ? 0f : 1f, show ? 1f : 0f)
); );
@ -125,7 +155,7 @@ public class PhotoStatusDisplayItem extends ImageStatusDisplayItem{
@Override @Override
public void onAnimationEnd(Animator animation){ public void onAnimationEnd(Animator animation){
if(show){ if(show){
altTextButton.setVisibility(View.GONE); altOrNoAltButton.setVisibility(View.GONE);
}else{ }else{
altTextScroller.setVisibility(View.GONE); altTextScroller.setVisibility(View.GONE);
altTextClose.setVisibility(View.GONE); altTextClose.setVisibility(View.GONE);

View File

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

View File

@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="16dp" android:height="16dp" android:viewportWidth="16" android:viewportHeight="16">
<path android:pathData="M5.96 4.457C5.722 3.18 6.7 2 8 2s2.279 1.18 2.04 2.457l-0.856 4.56C9.077 9.587 8.58 10 8 10S6.923 9.587 6.816 9.017L5.96 4.457zM9.5 12.5C9.5 13.328 8.828 14 8 14s-1.5-0.672-1.5-1.5S7.172 11 8 11s1.5 0.672 1.5 1.5z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
<path android:pathData="M10 2C8.343 2 7 3.343 7 5c0 2.227 0.789 5.204 1.225 6.685C8.459 12.48 9.19 13 10 13c0.81 0 1.54-0.518 1.775-1.31C12.212 10.213 13 7.25 13 5c0-1.657-1.343-3-3-3zm0 12c-1.105 0-2 0.895-2 2s0.895 2 2 2 2-0.895 2-2-0.895-2-2-2z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:pathData="M12 2.002c-2.14 0-3.875 1.735-3.875 3.875 0 2.92 1.207 6.552 1.813 8.199 0.323 0.878 1.159 1.423 2.064 1.423 0.904 0 1.739-0.542 2.063-1.418 0.606-1.64 1.81-5.254 1.81-8.204 0-2.14-1.734-3.875-3.875-3.875zm0.001 14.999c-1.381 0-2.501 1.12-2.501 2.501 0 1.381 1.12 2.501 2.501 2.501 1.382 0 2.501-1.12 2.501-2.5 0-1.382-1.12-2.502-2.5-2.502z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:pathData="M6.25 3C4.455 3 3 4.455 3 6.25v2.12c0 0.414 0.336 0.75 0.75 0.75S4.5 8.784 4.5 8.37V6.25c0-0.966 0.784-1.75 1.75-1.75h2.12c0.414 0 0.75-0.336 0.75-0.75S8.784 3 8.37 3H6.25zm9.38 1.5c-0.414 0-0.75-0.336-0.75-0.75S15.216 3 15.63 3h2.12C19.545 3 21 4.455 21 6.25v2.12c0 0.414-0.336 0.75-0.75 0.75S19.5 8.784 19.5 8.37V6.25c0-0.966-0.784-1.75-1.75-1.75h-2.12zM3 15.63c0-0.414 0.336-0.75 0.75-0.75s0.75 0.336 0.75 0.75v2.12c0 0.906 0.689 1.651 1.571 1.741C6.13 19.497 6.19 19.5 6.25 19.5h2.12c0.414 0 0.75 0.336 0.75 0.75S8.784 21 8.37 21H6.25C4.455 21 3 19.545 3 17.75v-2.12zm16.5 0c0-0.414 0.336-0.75 0.75-0.75S21 15.216 21 15.63v2.12c0 1.683-1.279 3.067-2.918 3.233C17.973 20.994 17.862 21 17.75 21h-2.12c-0.414 0-0.75-0.336-0.75-0.75s0.336-0.75 0.75-0.75h2.12c0.906 0 1.651-0.689 1.741-1.571 0.006-0.059 0.009-0.119 0.009-0.179v-2.12zM7 7.75C7 7.336 7.336 7 7.75 7h8.5C16.664 7 17 7.336 17 7.75S16.664 8.5 16.25 8.5h-8.5C7.336 8.5 7 8.164 7 7.75zM7.75 11C7.336 11 7 11.336 7 11.75s0.336 0.75 0.75 0.75h8.5c0.414 0 0.75-0.336 0.75-0.75S16.664 11 16.25 11h-8.5zM7 15.75C7 15.336 7.336 15 7.75 15h4.5c0.414 0 0.75 0.336 0.75 0.75s-0.336 0.75-0.75 0.75h-4.5C7.336 16.5 7 16.164 7 15.75z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@ -20,13 +20,21 @@
android:layout_margin="12dp" android:layout_margin="12dp"
android:importantForAccessibility="noHideDescendants" android:importantForAccessibility="noHideDescendants"
android:background="@drawable/bg_image_alt_overlay"> android:background="@drawable/bg_image_alt_overlay">
<ImageView
android:id="@+id/no_alt_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:src="@drawable/ic_fluent_important_20_filled"
android:tint="@color/gray_25" />
<TextView <TextView
android:id="@+id/alt_button" android:id="@+id/alt_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAppearance="@style/m3_label_large" android:textAppearance="@style/m3_label_large"
android:textColor="#FFF" android:textColor="@color/gray_25"
android:gravity="center" android:gravity="center"
android:includeFontPadding="false" android:includeFontPadding="false"
android:paddingHorizontal="5dp" android:paddingHorizontal="5dp"
@ -40,7 +48,7 @@
android:layout_gravity="end|top" android:layout_gravity="end|top"
android:src="@drawable/ic_baseline_close_24" android:src="@drawable/ic_baseline_close_24"
android:tint="#FFF" android:tint="#FFF"
android:background="?android:selectableItemBackgroundBorderless"/> android:background="?android:actionBarItemBackground"/>
<org.joinmastodon.android.ui.views.NestableScrollView <org.joinmastodon.android.ui.views.NestableScrollView
android:id="@+id/alt_text_scroller" android:id="@+id/alt_text_scroller"

View File

@ -231,4 +231,7 @@
<string name="sk_no_results">No results</string> <string name="sk_no_results">No results</string>
<string name="sk_save_draft">Save draft?</string> <string name="sk_save_draft">Save draft?</string>
<string name="sk_save_draft_message">Do you want to save your changes to this draft or publish it now?</string> <string name="sk_save_draft_message">Do you want to save your changes to this draft or publish it now?</string>
<string name="sk_no_alt_text">No alt text available</string>
<string name="sk_settings_show_alt_indicator">Indicator for alt texts</string>
<string name="sk_settings_show_no_alt_indicator">Indicator for missing alt texts</string>
</resources> </resources>