Better handling of filter expiration date (#212)
* Better handling of filter expiration date * Simplify Thread and Home Timeline filtering
This commit is contained in:
parent
3a962c7c05
commit
98b96c78d7
|
@ -19,9 +19,11 @@ import android.widget.Button;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toolbar;
|
import android.widget.Toolbar;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
import org.joinmastodon.android.E;
|
import org.joinmastodon.android.E;
|
||||||
|
@ -43,12 +45,9 @@ import org.joinmastodon.android.utils.StatusFilterPredicate;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import me.grishka.appkit.Nav;
|
import me.grishka.appkit.Nav;
|
||||||
import me.grishka.appkit.api.Callback;
|
import me.grishka.appkit.api.Callback;
|
||||||
import me.grishka.appkit.api.ErrorResponse;
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
|
@ -266,18 +265,14 @@ public class HomeTimelineFragment extends StatusListFragment{
|
||||||
List<StatusDisplayItem> targetList=displayItems.subList(gapPos, gapPos+1);
|
List<StatusDisplayItem> targetList=displayItems.subList(gapPos, gapPos+1);
|
||||||
targetList.clear();
|
targetList.clear();
|
||||||
List<Status> insertedPosts=data.subList(gapPostIndex+1, gapPostIndex+1);
|
List<Status> insertedPosts=data.subList(gapPostIndex+1, gapPostIndex+1);
|
||||||
List<Filter> filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(Filter.FilterContext.HOME)).collect(Collectors.toList());
|
StatusFilterPredicate filterPredicate=new StatusFilterPredicate(accountID, Filter.FilterContext.HOME);
|
||||||
outer:
|
|
||||||
for(Status s:result){
|
for(Status s:result){
|
||||||
if(idsBelowGap.contains(s.id))
|
if(idsBelowGap.contains(s.id))
|
||||||
break;
|
break;
|
||||||
for(Filter filter:filters){
|
if(filterPredicate.test(s)){
|
||||||
if(filter.matches(s)){
|
targetList.addAll(buildDisplayItems(s));
|
||||||
continue outer;
|
insertedPosts.add(s);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
targetList.addAll(buildDisplayItems(s));
|
|
||||||
insertedPosts.add(s);
|
|
||||||
}
|
}
|
||||||
if(targetList.isEmpty()){
|
if(targetList.isEmpty()){
|
||||||
// oops. We didn't add new posts, but at least we know there are none.
|
// oops. We didn't add new posts, but at least we know there are none.
|
||||||
|
|
|
@ -5,7 +5,6 @@ import android.view.View;
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.requests.statuses.GetStatusContext;
|
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.events.StatusCreatedEvent;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
import org.joinmastodon.android.model.Filter;
|
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.displayitems.TextStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
import org.joinmastodon.android.utils.StatusFilterPredicate;
|
||||||
import org.parceler.Parcels;
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -92,16 +92,10 @@ public class ThreadFragment extends StatusListFragment{
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Status> filterStatuses(List<Status> statuses){
|
private List<Status> filterStatuses(List<Status> statuses){
|
||||||
List<Filter> filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(Filter.FilterContext.THREAD)).collect(Collectors.toList());
|
StatusFilterPredicate statusFilterPredicate=new StatusFilterPredicate(accountID,Filter.FilterContext.THREAD);
|
||||||
if(filters.isEmpty())
|
return statuses.stream()
|
||||||
return statuses;
|
.filter(statusFilterPredicate)
|
||||||
return statuses.stream().filter(status->{
|
.collect(Collectors.toList());
|
||||||
for(Filter filter:filters){
|
|
||||||
if(filter.matches(status))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,12 +6,14 @@ import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.ObjectValidationException;
|
import org.joinmastodon.android.api.ObjectValidationException;
|
||||||
import org.joinmastodon.android.api.RequiredField;
|
import org.joinmastodon.android.api.RequiredField;
|
||||||
|
import org.parceler.Parcel;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@Parcel
|
||||||
public class Filter extends BaseModel{
|
public class Filter extends BaseModel{
|
||||||
@RequiredField
|
@RequiredField
|
||||||
public String id;
|
public String id;
|
||||||
|
@ -21,6 +23,7 @@ public class Filter extends BaseModel{
|
||||||
public Instant expiresAt;
|
public Instant expiresAt;
|
||||||
public boolean irreversible;
|
public boolean irreversible;
|
||||||
public boolean wholeWord;
|
public boolean wholeWord;
|
||||||
|
public FilterAction filterAction;
|
||||||
|
|
||||||
@SerializedName("context")
|
@SerializedName("context")
|
||||||
private List<FilterContext> _context;
|
private List<FilterContext> _context;
|
||||||
|
@ -76,4 +79,11 @@ public class Filter extends BaseModel{
|
||||||
@SerializedName("thread")
|
@SerializedName("thread")
|
||||||
THREAD
|
THREAD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum FilterAction{
|
||||||
|
@SerializedName("hide")
|
||||||
|
HIDE,
|
||||||
|
@SerializedName("warn")
|
||||||
|
WARN
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.model.Filter;
|
import org.joinmastodon.android.model.Filter;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -21,6 +22,16 @@ public class StatusFilterPredicate implements Predicate<Status>{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Status status){
|
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){
|
for(Filter filter:filters){
|
||||||
if(filter.matches(status))
|
if(filter.matches(status))
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue