Settings M3 redesign wip
This commit is contained in:
@@ -1,79 +1,56 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
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;
|
||||
|
||||
@RequiredField
|
||||
public String phrase;
|
||||
public transient EnumSet<FilterContext> context=EnumSet.noneOf(FilterContext.class);
|
||||
public String title;
|
||||
|
||||
@RequiredField
|
||||
public EnumSet<FilterContext> context;
|
||||
|
||||
public Instant expiresAt;
|
||||
public boolean irreversible;
|
||||
public boolean wholeWord;
|
||||
public FilterAction filterAction;
|
||||
|
||||
@SerializedName("context")
|
||||
private List<FilterContext> _context;
|
||||
@RequiredField
|
||||
public List<FilterKeyword> keywords;
|
||||
|
||||
private transient Pattern pattern;
|
||||
@RequiredField
|
||||
public List<FilterStatus> statuses;
|
||||
|
||||
@Override
|
||||
public void postprocess() throws ObjectValidationException{
|
||||
super.postprocess();
|
||||
if(_context==null)
|
||||
throw new ObjectValidationException();
|
||||
for(FilterContext c:_context){
|
||||
if(c!=null)
|
||||
context.add(c);
|
||||
}
|
||||
for(FilterKeyword keyword:keywords)
|
||||
keyword.postprocess();
|
||||
for(FilterStatus status:statuses)
|
||||
status.postprocess();
|
||||
}
|
||||
|
||||
public boolean matches(CharSequence text){
|
||||
if(TextUtils.isEmpty(text))
|
||||
return false;
|
||||
if(pattern==null){
|
||||
if(wholeWord)
|
||||
pattern=Pattern.compile("\\b"+Pattern.quote(phrase)+"\\b", Pattern.CASE_INSENSITIVE);
|
||||
else
|
||||
pattern=Pattern.compile(Pattern.quote(phrase), Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
return pattern.matcher(text).find();
|
||||
}
|
||||
|
||||
public boolean matches(Status status){
|
||||
return matches(status.getContentStatus().getStrippedText());
|
||||
public boolean isActive(){
|
||||
return expiresAt==null || expiresAt.isAfter(Instant.now());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Filter{"+
|
||||
"id='"+id+'\''+
|
||||
", phrase='"+phrase+'\''+
|
||||
", title='"+title+'\''+
|
||||
", context="+context+
|
||||
", expiresAt="+expiresAt+
|
||||
", irreversible="+irreversible+
|
||||
", wholeWord="+wholeWord+
|
||||
", filterAction="+filterAction+
|
||||
", keywords="+keywords+
|
||||
", statuses="+statuses+
|
||||
'}';
|
||||
}
|
||||
|
||||
public enum FilterContext{
|
||||
@SerializedName("home")
|
||||
HOME,
|
||||
@SerializedName("notifications")
|
||||
NOTIFICATIONS,
|
||||
@SerializedName("public")
|
||||
PUBLIC,
|
||||
@SerializedName("thread")
|
||||
THREAD
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public enum FilterAction{
|
||||
@SerializedName("warn")
|
||||
WARN,
|
||||
@SerializedName("hide")
|
||||
HIDE
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
public enum FilterContext{
|
||||
@SerializedName("home")
|
||||
HOME,
|
||||
@SerializedName("notifications")
|
||||
NOTIFICATIONS,
|
||||
@SerializedName("public")
|
||||
PUBLIC,
|
||||
@SerializedName("thread")
|
||||
THREAD,
|
||||
@SerializedName("account")
|
||||
ACCOUNT;
|
||||
|
||||
@StringRes
|
||||
public int getDisplayNameRes(){
|
||||
return switch(this){
|
||||
case HOME -> R.string.filter_context_home_lists;
|
||||
case NOTIFICATIONS -> R.string.filter_context_notifications;
|
||||
case PUBLIC -> R.string.filter_context_public_timelines;
|
||||
case THREAD -> R.string.filter_context_threads_replies;
|
||||
case ACCOUNT -> R.string.filter_context_profiles;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
||||
import org.parceler.Parcel;
|
||||
|
||||
@AllFieldsAreRequired
|
||||
@Parcel
|
||||
public class FilterKeyword extends BaseModel{
|
||||
public String id;
|
||||
public String keyword;
|
||||
public boolean wholeWord;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "FilterKeyword{"+
|
||||
"id='"+id+'\''+
|
||||
", keyword='"+keyword+'\''+
|
||||
", wholeWord="+wholeWord+
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
||||
import org.parceler.Parcel;
|
||||
|
||||
@AllFieldsAreRequired
|
||||
@Parcel
|
||||
public class FilterStatus extends BaseModel{
|
||||
public String id;
|
||||
public String statusId;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import org.joinmastodon.android.api.ObjectValidationException;
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class LegacyFilter extends BaseModel{
|
||||
@RequiredField
|
||||
public String id;
|
||||
@RequiredField
|
||||
public String phrase;
|
||||
public transient EnumSet<FilterContext> context=EnumSet.noneOf(FilterContext.class);
|
||||
public Instant expiresAt;
|
||||
public boolean irreversible;
|
||||
public boolean wholeWord;
|
||||
|
||||
@SerializedName("context")
|
||||
private List<FilterContext> _context;
|
||||
|
||||
private transient Pattern pattern;
|
||||
|
||||
@Override
|
||||
public void postprocess() throws ObjectValidationException{
|
||||
super.postprocess();
|
||||
if(_context==null)
|
||||
throw new ObjectValidationException();
|
||||
for(FilterContext c:_context){
|
||||
if(c!=null)
|
||||
context.add(c);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean matches(CharSequence text){
|
||||
if(TextUtils.isEmpty(text))
|
||||
return false;
|
||||
if(pattern==null){
|
||||
if(wholeWord)
|
||||
pattern=Pattern.compile("\\b"+Pattern.quote(phrase)+"\\b", Pattern.CASE_INSENSITIVE);
|
||||
else
|
||||
pattern=Pattern.compile(Pattern.quote(phrase), Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
return pattern.matcher(text).find();
|
||||
}
|
||||
|
||||
public boolean matches(Status status){
|
||||
return matches(status.getContentStatus().getStrippedText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Filter{"+
|
||||
"id='"+id+'\''+
|
||||
", phrase='"+phrase+'\''+
|
||||
", context="+context+
|
||||
", expiresAt="+expiresAt+
|
||||
", irreversible="+irreversible+
|
||||
", wholeWord="+wholeWord+
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import android.text.SpannableStringBuilder;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class ParsedAccount{
|
||||
public Account account;
|
||||
public CharSequence parsedName, parsedBio;
|
||||
public CustomEmojiHelper emojiHelper;
|
||||
public ImageLoaderRequest avatarRequest;
|
||||
|
||||
public ParsedAccount(Account account, String accountID){
|
||||
this.account=account;
|
||||
parsedName=HtmlParser.parseCustomEmoji(account.displayName, account.emojis);
|
||||
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);
|
||||
|
||||
emojiHelper=new CustomEmojiHelper();
|
||||
SpannableStringBuilder ssb=new SpannableStringBuilder(parsedName);
|
||||
ssb.append(parsedBio);
|
||||
emojiHelper.setText(ssb);
|
||||
|
||||
avatarRequest=new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic, V.dp(40), V.dp(40));
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public class Poll extends BaseModel{
|
||||
@RequiredField
|
||||
public String id;
|
||||
public Instant expiresAt;
|
||||
private boolean expired;
|
||||
public boolean expired;
|
||||
public boolean multiple;
|
||||
public int votersCount;
|
||||
public int votesCount;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package org.joinmastodon.android.model.viewmodel;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.AccountField;
|
||||
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
import me.grishka.appkit.utils.V;
|
||||
@@ -14,14 +17,19 @@ public class AccountViewModel{
|
||||
public final Account account;
|
||||
public final ImageLoaderRequest avaRequest;
|
||||
public final CustomEmojiHelper emojiHelper;
|
||||
public final CharSequence parsedName;
|
||||
public final CharSequence parsedName, parsedBio;
|
||||
public final String verifiedLink;
|
||||
|
||||
public AccountViewModel(Account account){
|
||||
public AccountViewModel(Account account, String accountID){
|
||||
this.account=account;
|
||||
avaRequest=new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? account.avatar : account.avatarStatic, V.dp(50), V.dp(50));
|
||||
emojiHelper=new CustomEmojiHelper();
|
||||
emojiHelper.setText(parsedName=HtmlParser.parseCustomEmoji(account.displayName, account.emojis));
|
||||
if(AccountSessionManager.get(accountID).getLocalPreferences().customEmojiInNames)
|
||||
parsedName=HtmlParser.parseCustomEmoji(account.displayName, account.emojis);
|
||||
else
|
||||
parsedName=account.displayName;
|
||||
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);
|
||||
emojiHelper.setText(parsedName);
|
||||
String verifiedLink=null;
|
||||
for(AccountField fld:account.fields){
|
||||
if(fld.verifiedAt!=null){
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.joinmastodon.android.model.viewmodel;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class CheckableListItem<T> extends ListItem<T>{
|
||||
public Style style;
|
||||
public boolean checked;
|
||||
public Consumer<Boolean> checkedChangeListener;
|
||||
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, int iconRes, Runnable onClick, T parentObject, boolean dividerAfter){
|
||||
super(title, subtitle, iconRes, onClick, parentObject, 0, dividerAfter);
|
||||
this.style=style;
|
||||
this.checked=checked;
|
||||
}
|
||||
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, Runnable onClick){
|
||||
this(title, subtitle, style, checked, 0, onClick, null, false);
|
||||
}
|
||||
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, Runnable onClick, T parentObject){
|
||||
this(title, subtitle, style, checked, 0, onClick, parentObject, false);
|
||||
}
|
||||
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, int iconRes, Runnable onClick){
|
||||
this(title, subtitle, style, checked, iconRes, onClick, null, false);
|
||||
}
|
||||
|
||||
public CheckableListItem(String title, String subtitle, Style style, boolean checked, int iconRes, Runnable onClick, T parentObject){
|
||||
this(title, subtitle, style, checked, iconRes, onClick, parentObject, false);
|
||||
}
|
||||
|
||||
public CheckableListItem(int titleRes, int subtitleRes, Style style, boolean checked, Runnable onClick){
|
||||
this(titleRes, subtitleRes, style, checked, 0, onClick, false);
|
||||
}
|
||||
|
||||
public CheckableListItem(int titleRes, int subtitleRes, Style style, boolean checked, Runnable onClick, boolean dividerAfter){
|
||||
this(titleRes, subtitleRes, style, checked, 0, onClick, dividerAfter);
|
||||
}
|
||||
|
||||
public CheckableListItem(int titleRes, int subtitleRes, Style style, boolean checked, int iconRes, Runnable onClick){
|
||||
this(titleRes, subtitleRes, style, checked, iconRes, onClick, false);
|
||||
}
|
||||
|
||||
public CheckableListItem(int titleRes, int subtitleRes, Style style, boolean checked, int iconRes, Runnable onClick, boolean dividerAfter){
|
||||
super(titleRes, subtitleRes, iconRes, onClick, 0, dividerAfter);
|
||||
this.style=style;
|
||||
this.checked=checked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(){
|
||||
return switch(style){
|
||||
case CHECKBOX -> R.id.list_item_checkbox;
|
||||
case RADIO -> R.id.list_item_radio;
|
||||
case SWITCH -> R.id.list_item_switch;
|
||||
};
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked){
|
||||
this.checked=checked;
|
||||
}
|
||||
|
||||
public void toggle(){
|
||||
checked=!checked;
|
||||
}
|
||||
|
||||
public enum Style{
|
||||
CHECKBOX,
|
||||
RADIO,
|
||||
SWITCH
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package org.joinmastodon.android.model.viewmodel;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
public class ListItem<T>{
|
||||
public String title;
|
||||
public String subtitle;
|
||||
@StringRes
|
||||
public int titleRes;
|
||||
@StringRes
|
||||
public int subtitleRes;
|
||||
@DrawableRes
|
||||
public int iconRes;
|
||||
public int colorOverrideAttr;
|
||||
public boolean dividerAfter;
|
||||
public Runnable onClick;
|
||||
public boolean isEnabled=true;
|
||||
public T parentObject;
|
||||
|
||||
public ListItem(String title, String subtitle, int iconRes, Runnable onClick, T parentObject, int colorOverrideAttr, boolean dividerAfter){
|
||||
this.title=title;
|
||||
this.subtitle=subtitle;
|
||||
this.iconRes=iconRes;
|
||||
this.colorOverrideAttr=colorOverrideAttr;
|
||||
this.dividerAfter=dividerAfter;
|
||||
this.onClick=onClick;
|
||||
this.parentObject=parentObject;
|
||||
if(onClick==null)
|
||||
isEnabled=false;
|
||||
}
|
||||
|
||||
public ListItem(String title, String subtitle, Runnable onClick){
|
||||
this(title, subtitle, 0, onClick, null, 0, false);
|
||||
}
|
||||
|
||||
public ListItem(String title, String subtitle, Runnable onClick, T parentObject){
|
||||
this(title, subtitle, 0, onClick, parentObject, 0, false);
|
||||
}
|
||||
|
||||
public ListItem(String title, String subtitle, @DrawableRes int iconRes, Runnable onClick){
|
||||
this(title, subtitle, iconRes, onClick, null, 0, false);
|
||||
}
|
||||
|
||||
public ListItem(String title, String subtitle, @DrawableRes int iconRes, Runnable onClick, T parentObject){
|
||||
this(title, subtitle, iconRes, onClick, parentObject, 0, false);
|
||||
}
|
||||
|
||||
public ListItem(@StringRes int titleRes, @StringRes int subtitleRes, Runnable onClick){
|
||||
this(null, null, 0, onClick, null, 0, false);
|
||||
this.titleRes=titleRes;
|
||||
this.subtitleRes=subtitleRes;
|
||||
}
|
||||
|
||||
public ListItem(@StringRes int titleRes, @StringRes int subtitleRes, Runnable onClick, int colorOverrideAttr, boolean dividerAfter){
|
||||
this(null, null, 0, onClick, null, colorOverrideAttr, dividerAfter);
|
||||
this.titleRes=titleRes;
|
||||
this.subtitleRes=subtitleRes;
|
||||
}
|
||||
|
||||
public ListItem(@StringRes int titleRes, @StringRes int subtitleRes, @DrawableRes int iconRes, Runnable onClick){
|
||||
this(null, null, iconRes, onClick, null, 0, false);
|
||||
this.titleRes=titleRes;
|
||||
this.subtitleRes=subtitleRes;
|
||||
}
|
||||
|
||||
public ListItem(@StringRes int titleRes, @StringRes int subtitleRes, @DrawableRes int iconRes, Runnable onClick, int colorOverrideAttr, boolean dividerAfter){
|
||||
this(null, null, iconRes, onClick, null, colorOverrideAttr, dividerAfter);
|
||||
this.titleRes=titleRes;
|
||||
this.subtitleRes=subtitleRes;
|
||||
}
|
||||
|
||||
public int getItemViewType(){
|
||||
return colorOverrideAttr==0 ? R.id.list_item_simple : R.id.list_item_simple_tinted;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user