diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java index 19c13e1c9..c659bc3ff 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java @@ -19,9 +19,11 @@ import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; -import android.widget.TextView; import android.widget.Toolbar; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + import com.squareup.otto.Subscribe; import org.joinmastodon.android.E; @@ -43,12 +45,9 @@ import org.joinmastodon.android.utils.StatusFilterPredicate; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Set; import java.util.stream.Collectors; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; import me.grishka.appkit.Nav; import me.grishka.appkit.api.Callback; import me.grishka.appkit.api.ErrorResponse; @@ -266,18 +265,14 @@ public class HomeTimelineFragment extends StatusListFragment{ List targetList=displayItems.subList(gapPos, gapPos+1); targetList.clear(); List insertedPosts=data.subList(gapPostIndex+1, gapPostIndex+1); - List filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(Filter.FilterContext.HOME)).collect(Collectors.toList()); - outer: + StatusFilterPredicate filterPredicate=new StatusFilterPredicate(accountID, Filter.FilterContext.HOME); for(Status s:result){ if(idsBelowGap.contains(s.id)) break; - for(Filter filter:filters){ - if(filter.matches(s)){ - continue outer; - } + if(filterPredicate.test(s)){ + targetList.addAll(buildDisplayItems(s)); + insertedPosts.add(s); } - targetList.addAll(buildDisplayItems(s)); - insertedPosts.add(s); } if(targetList.isEmpty()){ // oops. We didn't add new posts, but at least we know there are none. diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java index 4578617c4..b4de4d184 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ThreadFragment.java @@ -5,7 +5,6 @@ import android.view.View; import org.joinmastodon.android.R; import org.joinmastodon.android.api.requests.statuses.GetStatusContext; -import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.events.StatusCreatedEvent; import org.joinmastodon.android.model.Account; import org.joinmastodon.android.model.Filter; @@ -17,6 +16,7 @@ import org.joinmastodon.android.ui.displayitems.StatusDisplayItem; import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem; import org.joinmastodon.android.ui.text.HtmlParser; import org.joinmastodon.android.ui.utils.UiUtils; +import org.joinmastodon.android.utils.StatusFilterPredicate; import org.parceler.Parcels; import java.util.Collections; @@ -92,16 +92,10 @@ public class ThreadFragment extends StatusListFragment{ } private List filterStatuses(List statuses){ - List filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(Filter.FilterContext.THREAD)).collect(Collectors.toList()); - if(filters.isEmpty()) - return statuses; - return statuses.stream().filter(status->{ - for(Filter filter:filters){ - if(filter.matches(status)) - return false; - } - return true; - }).collect(Collectors.toList()); + StatusFilterPredicate statusFilterPredicate=new StatusFilterPredicate(accountID,Filter.FilterContext.THREAD); + return statuses.stream() + .filter(statusFilterPredicate) + .collect(Collectors.toList()); } @Override diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/Filter.java b/mastodon/src/main/java/org/joinmastodon/android/model/Filter.java index 8a629a290..f7b394765 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/Filter.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/Filter.java @@ -6,12 +6,14 @@ import com.google.gson.annotations.SerializedName; import org.joinmastodon.android.api.ObjectValidationException; import org.joinmastodon.android.api.RequiredField; +import org.parceler.Parcel; import java.time.Instant; import java.util.EnumSet; import java.util.List; import java.util.regex.Pattern; +@Parcel public class Filter extends BaseModel{ @RequiredField public String id; @@ -21,6 +23,7 @@ public class Filter extends BaseModel{ public Instant expiresAt; public boolean irreversible; public boolean wholeWord; + public FilterAction filterAction; @SerializedName("context") private List _context; @@ -76,4 +79,11 @@ public class Filter extends BaseModel{ @SerializedName("thread") THREAD } + + public enum FilterAction{ + @SerializedName("hide") + HIDE, + @SerializedName("warn") + WARN + } } 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 cf9e0829f..4555cdfdb 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java +++ b/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java @@ -4,6 +4,7 @@ import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.model.Filter; import org.joinmastodon.android.model.Status; +import java.time.Instant; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -21,6 +22,16 @@ public class StatusFilterPredicate implements Predicate{ @Override public boolean test(Status status){ + if(status.filtered!=null){ + if (status.filtered.isEmpty()){ + return true; + } + boolean matches=status.filtered.stream() + .map(filterResult->filterResult.filter) + .filter(filter->filter.expiresAt==null||filter.expiresAt.isAfter(Instant.now())) + .anyMatch(filter->filter.filterAction==Filter.FilterAction.HIDE); + return !matches; + } for(Filter filter:filters){ if(filter.matches(status)) return false;