Merge branch 'feature/hide_alttext'
# Conflicts: # mastodon/src/androidTest/java/org/joinmastodon/android/utils/StatusFilterPredicateTest.java # mastodon/src/main/java/org/joinmastodon/android/fragments/settings/TimeLineFragment.java # mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/WarningFilteredStatusDisplayItem.java # mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java # mastodon/src/main/res/values-de-rDE/strings_mo.xml # mastodon/src/main/res/values/strings_mo.xml
This commit is contained in:
@@ -19,7 +19,9 @@ public class StatusFilterPredicateTest {
|
||||
|
||||
private static final Status
|
||||
hideInHomePublic = Status.ofFake(null, "hide me, please", Instant.now()),
|
||||
warnInHomePublic = Status.ofFake(null, "display me with a warning", Instant.now());
|
||||
warnInHomePublic = Status.ofFake(null, "display me with a warning", Instant.now()),
|
||||
noAltText = Status.ofFake(null, "display me with a warning", Instant.now()),
|
||||
withAltText = Status.ofFake(null, "display me with a warning", Instant.now());
|
||||
|
||||
static {
|
||||
hideMeFilter.phrase = "hide me";
|
||||
@@ -29,6 +31,12 @@ public class StatusFilterPredicateTest {
|
||||
warnMeFilter.phrase = "warning";
|
||||
warnMeFilter.filterAction = WARN;
|
||||
warnMeFilter.context = EnumSet.of(PUBLIC, HOME);
|
||||
|
||||
noAltText.mediaAttachments = Attachment.createFakeAttachments("fakeurl", new ColorDrawable());
|
||||
withAltText.mediaAttachments = Attachment.createFakeAttachments("fakeurl", new ColorDrawable());
|
||||
for (Attachment mediaAttachment : withAltText.mediaAttachments) {
|
||||
mediaAttachment.description = "Alt Text";
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -78,4 +86,16 @@ public class StatusFilterPredicateTest {
|
||||
assertTrue("should pass because matching filter is for hiding",
|
||||
new StatusFilterPredicate(allFilters, HOME, WARN).test(hideInHomePublic));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAltTextFilterNoPass() {
|
||||
assertFalse("should not pass because of no alt text",
|
||||
new StatusFilterPredicate(allFilters, HOME).test(noAltText));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAltTextFilterPass() {
|
||||
assertTrue("should pass because of alt text",
|
||||
new StatusFilterPredicate(allFilters, HOME).test(withAltText));
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.ContentType;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.joinmastodon.android.model.TimelineDefinition;
|
||||
import org.joinmastodon.android.ui.utils.ColorPalette;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
@@ -48,6 +47,7 @@ public class GlobalUserPreferences{
|
||||
public static boolean reduceMotion;
|
||||
public static boolean showAltIndicator;
|
||||
public static boolean showNoAltIndicator;
|
||||
public static boolean showPostsWithoutAlt;
|
||||
public static boolean enablePreReleases;
|
||||
public static PrefixRepliesMode prefixReplies;
|
||||
public static boolean collapseLongPosts;
|
||||
@@ -118,6 +118,7 @@ public class GlobalUserPreferences{
|
||||
reduceMotion=prefs.getBoolean("reduceMotion", false);
|
||||
showAltIndicator=prefs.getBoolean("showAltIndicator", true);
|
||||
showNoAltIndicator=prefs.getBoolean("showNoAltIndicator", true);
|
||||
showPostsWithoutAlt =prefs.getBoolean("showPostsWithoutAlt", true);
|
||||
enablePreReleases=prefs.getBoolean("enablePreReleases", false);
|
||||
prefixReplies=PrefixRepliesMode.valueOf(prefs.getString("prefixReplies", PrefixRepliesMode.NEVER.name()));
|
||||
collapseLongPosts=prefs.getBoolean("collapseLongPosts", true);
|
||||
@@ -195,6 +196,7 @@ public class GlobalUserPreferences{
|
||||
.putBoolean("reduceMotion", reduceMotion)
|
||||
.putBoolean("showAltIndicator", showAltIndicator)
|
||||
.putBoolean("showNoAltIndicator", showNoAltIndicator)
|
||||
.putBoolean("showPostsWithoutAlt", showPostsWithoutAlt)
|
||||
.putBoolean("enablePreReleases", enablePreReleases)
|
||||
.putString("prefixReplies", prefixReplies.name())
|
||||
.putBoolean("collapseLongPosts", collapseLongPosts)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.jsoup.internal.StringUtil;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class AltTextFilter extends Filter {
|
||||
|
||||
public AltTextFilter(FilterAction filterAction, FilterContext firstContext, FilterContext... restContexts) {
|
||||
this.filterAction = filterAction;
|
||||
isRemote = false;
|
||||
context = EnumSet.of(firstContext, restContexts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Status status) {
|
||||
return status.getContentStatus().mediaAttachments.stream().map(attachment -> attachment.description).anyMatch(StringUtil::isBlank);
|
||||
}
|
||||
}
|
||||
@@ -4,18 +4,13 @@ import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.model.LegacyFilter;
|
||||
import org.joinmastodon.android.model.Filter;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.drawables.SawtoothTearDrawable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
// Mind the gap!
|
||||
@@ -55,7 +50,8 @@ public class WarningFilteredStatusDisplayItem extends StatusDisplayItem{
|
||||
@Override
|
||||
public void onBind(WarningFilteredStatusDisplayItem item) {
|
||||
filteredItems = item.filteredItems;
|
||||
text.setText(item.parentFragment.getString(R.string.sk_filtered, item.applyingFilter.title));
|
||||
String title = item.applyingFilter instanceof AltTextFilter ? item.parentFragment.getString(R.string.sk_no_alt_text) : item.applyingFilter.title;
|
||||
text.setText(item.parentFragment.getString(R.string.sk_filtered, title));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class StatusFilterPredicate implements Predicate<Status>{
|
||||
private List<LegacyFilter> clientFilters;
|
||||
private final List<LegacyFilter> filters;
|
||||
private final FilterContext context;
|
||||
private final FilterAction action;
|
||||
@@ -22,12 +23,14 @@ public class StatusFilterPredicate implements Predicate<Status>{
|
||||
/**
|
||||
* @param context null makes the predicate pass automatically
|
||||
* @param action defines what the predicate should check:
|
||||
* status should not be hidden or should not display with warning
|
||||
* status should not be hidden or should not display with warning
|
||||
*/
|
||||
public StatusFilterPredicate(List<LegacyFilter> filters, FilterContext context, FilterAction action){
|
||||
this.filters = filters;
|
||||
this.context = context;
|
||||
this.action = action;
|
||||
this.clientFilters = GlobalUserPreferences.showPostsWithoutAlt ? List.of()
|
||||
: List.of(new AltTextFilter(HIDE, HOME, PUBLIC, ACCOUNT), new AltTextFilter(WARN, THREAD, NOTIFICATIONS));
|
||||
}
|
||||
|
||||
public StatusFilterPredicate(List<LegacyFilter> filters, FilterContext context){
|
||||
@@ -54,7 +57,7 @@ public class StatusFilterPredicate implements Predicate<Status>{
|
||||
|
||||
/**
|
||||
* @return whether the status should be displayed without being hidden/warned about.
|
||||
* will always return true if the context is null.
|
||||
* will always return true if the context is null.
|
||||
* true = display this status,
|
||||
* false = filter this status
|
||||
*/
|
||||
@@ -77,6 +80,15 @@ public class StatusFilterPredicate implements Predicate<Status>{
|
||||
.filter(filter -> filter.filterAction == null ? action == FilterAction.HIDE : filter.filterAction == action)
|
||||
.findAny();
|
||||
|
||||
//Apply client filters if no server filter is triggered
|
||||
if (applyingFilter.isEmpty()) {
|
||||
applyingFilter = clientFilters.stream()
|
||||
.filter(filter -> filter.context.contains(context))
|
||||
.filter(filter -> filter.filterAction == null ? action == HIDE : filter.filterAction == action)
|
||||
.filter(filter -> filter.matches(status))
|
||||
.findAny();
|
||||
}
|
||||
|
||||
this.applyingFilter = applyingFilter.orElse(null);
|
||||
return applyingFilter.isEmpty();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_fluent_eye_off_24_regular"/>
|
||||
<item android:drawable="@drawable/ic_fluent_important_24_regular" android:top="14sp" android:width="10sp" android:height="10sp"/>
|
||||
</layer-list>
|
||||
@@ -75,6 +75,8 @@
|
||||
<string name="mo_setting_uniform_summary">App-Symbol für alle Benachrichtigungen verwenden</string>
|
||||
<string name="mo_setting_reduced_motion_summary">Animationen für Interaktionen deaktivieren</string>
|
||||
<string name="mo_setting_play_gif_summary">GIFs in Profilbildern und Emojis automatisch abspielen</string>
|
||||
<string name="mo_settings_show_posts_without_alt">Zeige Medienbeiträge ohne Bildbeschreibung</string>
|
||||
<string name="mo_settings_show_posts_without_alt_summary">Beiträge werden in allen Timelines ausgeblendet, können aber in Threads und Benachrichtungen angezeigt werden</string>
|
||||
<string name="mo_color_palette_black_and_white">Schwarz und Weiß</string>
|
||||
<string name="mo_haptic_feedback">Haptisches Feedback</string>
|
||||
<string name="mo_setting_haptic_feedback_summary">Vibrieren beim Interagieren mit Posts</string>
|
||||
|
||||
@@ -82,9 +82,11 @@
|
||||
<string name="mo_setting_disable_swipe_summary">Swipe to change viewed timeline</string>
|
||||
<string name="mo_setting_haptic_feedback_summary">Vibrate when interacting with posts</string>
|
||||
<string name="mo_swap_bookmark_with_reblog_summary">Bookmark or reblog posts from the notification</string>
|
||||
<string name="mo_settings_show_posts_without_alt_summary">Posts will be hidden in all timelines, but can be revealed in threads and notifications</string>
|
||||
|
||||
<!-- Settings -->
|
||||
<string name="mo_notification_audience_settings">Notification Audience</string>
|
||||
<string name="mo_settings_show_posts_without_alt">Show media posts with missing alt text</string>
|
||||
<string name="mo_double_tap_to_swipe_between_tabs">Double tap to swipe between tabs</string>
|
||||
<string name="mo_haptic_feedback">Haptic feedback</string>
|
||||
<string name="mo_swap_bookmark_with_reblog">Swap bookmark with reblog action</string>
|
||||
|
||||
Reference in New Issue
Block a user