diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/CacheController.java b/mastodon/src/main/java/org/joinmastodon/android/api/CacheController.java index f1dfcea3..2c113bcb 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/api/CacheController.java +++ b/mastodon/src/main/java/org/joinmastodon/android/api/CacheController.java @@ -20,6 +20,7 @@ import org.joinmastodon.android.model.Notification; import org.joinmastodon.android.model.PaginatedResponse; import org.joinmastodon.android.model.SearchResult; import org.joinmastodon.android.model.Status; +import org.joinmastodon.android.utils.StatusFilterPredicate; import java.io.IOException; import java.util.ArrayList; @@ -89,14 +90,7 @@ public class CacheController{ .setCallback(new Callback<>(){ @Override public void onSuccess(List result){ - callback.onSuccess(new CacheablePaginatedResponse<>(result.stream().filter(post->{ - for(Filter filter:filters){ - if(filter.matches(post.getContentStatus().content)){ - return false; - } - } - return true; - }).collect(Collectors.toList()), result.isEmpty() ? null : result.get(result.size()-1).id, false)); + callback.onSuccess(new CacheablePaginatedResponse<>(result.stream().filter(new StatusFilterPredicate(filters)).collect(Collectors.toList()), result.isEmpty() ? null : result.get(result.size()-1).id, false)); putHomeTimeline(result, maxID==null); } 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 db7033d2..20fac476 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java @@ -28,15 +28,18 @@ import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.events.StatusCreatedEvent; import org.joinmastodon.android.model.CacheablePaginatedResponse; +import org.joinmastodon.android.model.Filter; import org.joinmastodon.android.model.Status; import org.joinmastodon.android.ui.displayitems.GapStatusDisplayItem; import org.joinmastodon.android.ui.displayitems.StatusDisplayItem; import org.joinmastodon.android.ui.utils.UiUtils; +import org.joinmastodon.android.utils.StatusFilterPredicate; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; @@ -164,6 +167,10 @@ public class HomeTimelineFragment extends StatusListFragment{ result.get(result.size()-1).hasGapAfter=true; toAdd=result; } + List filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(Filter.FilterContext.HOME)).collect(Collectors.toList()); + if(!filters.isEmpty()){ + toAdd=toAdd.stream().filter(new StatusFilterPredicate(filters)).collect(Collectors.toList()); + } if(!toAdd.isEmpty()){ prependItems(toAdd, true); showNewPostsButton(); @@ -237,9 +244,16 @@ 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: for(Status s:result){ if(idsBelowGap.contains(s.id)) break; + for(Filter filter:filters){ + if(filter.matches(s.getContentStatus().content)){ + continue outer; + } + } targetList.addAll(buildDisplayItems(s)); insertedPosts.add(s); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/LocalTimelineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/LocalTimelineFragment.java index 03ac1a3c..76c804c3 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/LocalTimelineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/LocalTimelineFragment.java @@ -5,23 +5,29 @@ import android.view.View; import org.joinmastodon.android.api.requests.timelines.GetPublicTimeline; import org.joinmastodon.android.fragments.StatusListFragment; +import org.joinmastodon.android.model.Filter; import org.joinmastodon.android.model.Status; import org.joinmastodon.android.ui.utils.DiscoverInfoBannerHelper; +import org.joinmastodon.android.utils.StatusFilterPredicate; import java.util.List; +import java.util.stream.Collectors; import me.grishka.appkit.api.SimpleCallback; public class LocalTimelineFragment extends StatusListFragment{ private DiscoverInfoBannerHelper bannerHelper=new DiscoverInfoBannerHelper(DiscoverInfoBannerHelper.BannerType.LOCAL_TIMELINE); + private String maxID; @Override protected void doLoadData(int offset, int count){ - currentRequest=new GetPublicTimeline(true, false, refreshing ? null : getMaxID(), count) + currentRequest=new GetPublicTimeline(true, false, refreshing ? null : maxID, count) .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(List result){ - onDataLoaded(result, !result.isEmpty()); + if(!result.isEmpty()) + maxID=result.get(result.size()-1).id; + onDataLoaded(result.stream().filter(new StatusFilterPredicate(accountID, Filter.FilterContext.PUBLIC)).collect(Collectors.toList()), !result.isEmpty()); } }) .exec(accountID); diff --git a/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java b/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java new file mode 100644 index 00000000..1974c9b6 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java @@ -0,0 +1,31 @@ +package org.joinmastodon.android.utils; + +import org.joinmastodon.android.api.session.AccountSessionManager; +import org.joinmastodon.android.model.Filter; +import org.joinmastodon.android.model.Status; + +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class StatusFilterPredicate implements Predicate{ + private final List filters; + + public StatusFilterPredicate(List filters){ + this.filters=filters; + } + + public StatusFilterPredicate(String accountID, Filter.FilterContext context){ + filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(context)).collect(Collectors.toList()); + } + + @Override + public boolean test(Status status){ + CharSequence content=status.getContentStatus().content; + for(Filter filter:filters){ + if(filter.matches(content)) + return false; + } + return true; + } +}