From c38eb545b16a18bcb713a9639a49ce77b2e60307 Mon Sep 17 00:00:00 2001 From: sk Date: Sat, 27 May 2023 13:09:36 +0200 Subject: [PATCH] use matched filter for determining warning title fixes a bug where, when multiple filters apply, the WarningFilteredStatusDisplayItem would not check if the warning applies to the current context. now, matched filter is determined through the predicate (though not exactly what a predicate is supposed to do, i guess) and passed down to the WarningFilteredStatusDisplayItem. cc @LucasGGamerM --- .../ui/displayitems/StatusDisplayItem.java | 13 ++++++++----- .../WarningFilteredStatusDisplayItem.java | 7 +++++-- .../android/utils/StatusFilterPredicate.java | 16 +++++++++++++--- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java index 8014853b0..6932173bc 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java @@ -95,10 +95,6 @@ public abstract class StatusDisplayItem{ args.putString("account", accountID); ScheduledStatus scheduledStatus = parentObject instanceof ScheduledStatus ? (ScheduledStatus) parentObject : null; - if (!statusForContent.filterRevealed) { - statusForContent.filterRevealed = new StatusFilterPredicate(accountID, filterContext, Filter.FilterAction.WARN).test(status); - } - ReblogOrReplyLineStatusDisplayItem replyLine = null; boolean threadReply = statusForContent.inReplyToAccountId != null && statusForContent.inReplyToAccountId.equals(statusForContent.account.id); @@ -206,8 +202,15 @@ public abstract class StatusDisplayItem{ item.index=i++; } + Filter applyingFilter = null; + if (!statusForContent.filterRevealed) { + StatusFilterPredicate predicate = new StatusFilterPredicate(accountID, filterContext, Filter.FilterAction.WARN); + statusForContent.filterRevealed = predicate.test(status); + applyingFilter = predicate.getApplyingFilter(); + } + ArrayList result = statusForContent.filterRevealed ? items : - new ArrayList<>(List.of(new WarningFilteredStatusDisplayItem(parentID, fragment, statusForContent, items))); + new ArrayList<>(List.of(new WarningFilteredStatusDisplayItem(parentID, fragment, statusForContent, items, applyingFilter))); if (addFooter && status.hasGapAfter && !(fragment instanceof ThreadFragment)) { StatusDisplayItem gap = new GapStatusDisplayItem(parentID, fragment); diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/WarningFilteredStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/WarningFilteredStatusDisplayItem.java index fd1e91259..932a9bf10 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/WarningFilteredStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/WarningFilteredStatusDisplayItem.java @@ -7,6 +7,7 @@ import android.widget.TextView; import org.joinmastodon.android.R; import org.joinmastodon.android.fragments.BaseStatusListFragment; +import org.joinmastodon.android.model.Filter; import org.joinmastodon.android.model.Status; import java.util.List; @@ -15,11 +16,13 @@ public class WarningFilteredStatusDisplayItem extends StatusDisplayItem{ public boolean loading; public final Status status; public List filteredItems; + public Filter applyingFilter; - public WarningFilteredStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Status status, List filteredItems){ + public WarningFilteredStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Status status, List filteredItems, Filter applyingFilter){ super(parentID, parentFragment); this.status=status; this.filteredItems = filteredItems; + this.applyingFilter = applyingFilter; } @Override @@ -41,7 +44,7 @@ public class WarningFilteredStatusDisplayItem extends StatusDisplayItem{ @Override public void onBind(WarningFilteredStatusDisplayItem item) { filteredItems = item.filteredItems; - text.setText(item.parentFragment.getString(R.string.sk_filtered, item.status.filtered.get(item.status.filtered.size() -1).filter.title)); + text.setText(item.parentFragment.getString(R.string.sk_filtered, item.applyingFilter.title)); } @Override diff --git a/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java b/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java index 8c73d3a87..0c96bb9c0 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java +++ b/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java @@ -6,6 +6,7 @@ import org.joinmastodon.android.model.Status; import java.time.Instant; import java.util.List; +import java.util.Optional; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -14,6 +15,7 @@ public class StatusFilterPredicate implements Predicate{ private final List filters; private final Filter.FilterContext context; private final Filter.FilterAction action; + private Filter applyingFilter; /** * @param context null makes the predicate pass automatically @@ -58,18 +60,26 @@ public class StatusFilterPredicate implements Predicate{ public boolean test(Status status){ if (context == null) return true; - Stream stream = status.filtered != null + Stream matchingFilters = status.filtered != null // use server-provided per-status info (status.filtered) if available ? status.filtered.stream().map(f -> f.filter) // or fall back to cached filters : filters.stream().filter(filter -> filter.matches(status)); - return stream + Optional applyingFilter = matchingFilters // discard expired filters .filter(filter -> filter.expiresAt == null || filter.expiresAt.isAfter(Instant.now())) // only apply filters for given context .filter(filter -> filter.context.contains(context)) // treating filterAction = null (from filters list) as FilterAction.HIDE - .noneMatch(filter -> filter.filterAction == null ? action == Filter.FilterAction.HIDE : filter.filterAction == action); + .filter(filter -> filter.filterAction == null ? action == Filter.FilterAction.HIDE : filter.filterAction == action) + .findAny(); + + this.applyingFilter = applyingFilter.orElse(null); + return applyingFilter.isEmpty(); + } + + public Filter getApplyingFilter() { + return applyingFilter; } }