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
This commit is contained in:
parent
1fc2f81dab
commit
c38eb545b1
|
@ -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<StatusDisplayItem> 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);
|
||||
|
|
|
@ -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<StatusDisplayItem> filteredItems;
|
||||
public Filter applyingFilter;
|
||||
|
||||
public WarningFilteredStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, Status status, List<StatusDisplayItem> filteredItems){
|
||||
public WarningFilteredStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, Status status, List<StatusDisplayItem> 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
|
||||
|
|
|
@ -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<Status>{
|
|||
private final List<Filter> 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<Status>{
|
|||
public boolean test(Status status){
|
||||
if (context == null) return true;
|
||||
|
||||
Stream<Filter> stream = status.filtered != null
|
||||
Stream<Filter> 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<Filter> 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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue