forked from mirrors/Fedilab
parent
8bf21db632
commit
74599d8a7f
10 changed files with 274 additions and 162 deletions
|
@ -147,6 +147,7 @@ import app.fedilab.android.ui.fragment.timeline.FragmentMastodonConversation;
|
||||||
import app.fedilab.android.ui.fragment.timeline.FragmentMastodonTimeline;
|
import app.fedilab.android.ui.fragment.timeline.FragmentMastodonTimeline;
|
||||||
import app.fedilab.android.ui.fragment.timeline.FragmentNotificationContainer;
|
import app.fedilab.android.ui.fragment.timeline.FragmentNotificationContainer;
|
||||||
import app.fedilab.android.viewmodel.mastodon.AccountsVM;
|
import app.fedilab.android.viewmodel.mastodon.AccountsVM;
|
||||||
|
import app.fedilab.android.viewmodel.mastodon.FiltersVM;
|
||||||
import app.fedilab.android.viewmodel.mastodon.InstancesVM;
|
import app.fedilab.android.viewmodel.mastodon.InstancesVM;
|
||||||
import app.fedilab.android.viewmodel.mastodon.TimelinesVM;
|
import app.fedilab.android.viewmodel.mastodon.TimelinesVM;
|
||||||
import app.fedilab.android.viewmodel.mastodon.TopBarVM;
|
import app.fedilab.android.viewmodel.mastodon.TopBarVM;
|
||||||
|
@ -691,7 +692,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
||||||
editor.apply();
|
editor.apply();
|
||||||
});
|
});
|
||||||
//Retrieve filters
|
//Retrieve filters
|
||||||
new ViewModelProvider(BaseMainActivity.this).get(AccountsVM.class).getFilters(currentInstance, currentToken)
|
new ViewModelProvider(BaseMainActivity.this).get(FiltersVM.class).getFilters(currentInstance, currentToken)
|
||||||
.observe(BaseMainActivity.this, filters -> mainFilters = filters);
|
.observe(BaseMainActivity.this, filters -> mainFilters = filters);
|
||||||
new ViewModelProvider(BaseMainActivity.this).get(AccountsVM.class).getConnectedAccount(currentInstance, currentToken)
|
new ViewModelProvider(BaseMainActivity.this).get(AccountsVM.class).getConnectedAccount(currentInstance, currentToken)
|
||||||
.observe(BaseMainActivity.this, mastodonAccount -> {
|
.observe(BaseMainActivity.this, mastodonAccount -> {
|
||||||
|
|
|
@ -28,6 +28,8 @@ import android.widget.Button;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.appcompat.widget.AppCompatCheckBox;
|
||||||
|
import androidx.appcompat.widget.AppCompatEditText;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
@ -35,6 +37,7 @@ import androidx.lifecycle.ViewModelStoreOwner;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@ -42,11 +45,12 @@ import app.fedilab.android.BaseMainActivity;
|
||||||
import app.fedilab.android.R;
|
import app.fedilab.android.R;
|
||||||
import app.fedilab.android.client.entities.api.Filter;
|
import app.fedilab.android.client.entities.api.Filter;
|
||||||
import app.fedilab.android.databinding.ActivityFiltersBinding;
|
import app.fedilab.android.databinding.ActivityFiltersBinding;
|
||||||
|
import app.fedilab.android.databinding.KeywordsLayoutBinding;
|
||||||
import app.fedilab.android.databinding.PopupAddFilterBinding;
|
import app.fedilab.android.databinding.PopupAddFilterBinding;
|
||||||
import app.fedilab.android.helper.Helper;
|
import app.fedilab.android.helper.Helper;
|
||||||
import app.fedilab.android.helper.ThemeHelper;
|
import app.fedilab.android.helper.ThemeHelper;
|
||||||
import app.fedilab.android.ui.drawer.FilterAdapter;
|
import app.fedilab.android.ui.drawer.FilterAdapter;
|
||||||
import app.fedilab.android.viewmodel.mastodon.AccountsVM;
|
import app.fedilab.android.viewmodel.mastodon.FiltersVM;
|
||||||
|
|
||||||
public class FilterActivity extends BaseActivity implements FilterAdapter.Delete {
|
public class FilterActivity extends BaseActivity implements FilterAdapter.Delete {
|
||||||
|
|
||||||
|
@ -64,7 +68,7 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
|
||||||
public static void addEditFilter(Context context, Filter filter, FilterAdapter.FilterAction listener) {
|
public static void addEditFilter(Context context, Filter filter, FilterAdapter.FilterAction listener) {
|
||||||
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context, Helper.dialogStyle());
|
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context, Helper.dialogStyle());
|
||||||
PopupAddFilterBinding popupAddFilterBinding = PopupAddFilterBinding.inflate(LayoutInflater.from(context));
|
PopupAddFilterBinding popupAddFilterBinding = PopupAddFilterBinding.inflate(LayoutInflater.from(context));
|
||||||
AccountsVM accountsVM = new ViewModelProvider((ViewModelStoreOwner) context).get(AccountsVM.class);
|
FiltersVM filtersVM = new ViewModelProvider((ViewModelStoreOwner) context).get(FiltersVM.class);
|
||||||
dialogBuilder.setView(popupAddFilterBinding.getRoot());
|
dialogBuilder.setView(popupAddFilterBinding.getRoot());
|
||||||
ArrayAdapter<CharSequence> adapterResize = ArrayAdapter.createFromResource(Objects.requireNonNull(context),
|
ArrayAdapter<CharSequence> adapterResize = ArrayAdapter.createFromResource(Objects.requireNonNull(context),
|
||||||
R.array.filter_expire, android.R.layout.simple_spinner_dropdown_item);
|
R.array.filter_expire, android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
@ -103,8 +107,14 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
popupAddFilterBinding.addKeyword.setOnClickListener(v -> {
|
||||||
|
KeywordsLayoutBinding keywordsLayoutBinding = KeywordsLayoutBinding.inflate(LayoutInflater.from(context));
|
||||||
|
keywordsLayoutBinding.deleteKeyword.setOnClickListener(v2 -> popupAddFilterBinding.keywordsContainer.removeView(keywordsLayoutBinding.deleteKeyword));
|
||||||
|
popupAddFilterBinding.keywordsContainer.addView(keywordsLayoutBinding.getRoot());
|
||||||
|
});
|
||||||
|
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
popupAddFilterBinding.addPhrase.setText(filter.phrase);
|
popupAddFilterBinding.addTitle.setText(filter.title);
|
||||||
if (filter.context != null)
|
if (filter.context != null)
|
||||||
for (String val : filter.context) {
|
for (String val : filter.context) {
|
||||||
switch (val) {
|
switch (val) {
|
||||||
|
@ -125,14 +135,20 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
popupAddFilterBinding.contextWholeWord.setChecked(filter.whole_word);
|
if (filter.keywords != null && filter.keywords.size() > 0) {
|
||||||
if (filter.irreversible) {
|
for (Filter.FilterKeyword filterKeyword : filter.keywords) {
|
||||||
popupAddFilterBinding.actionRemove.setChecked(true);
|
KeywordsLayoutBinding keywordsLayoutBinding = KeywordsLayoutBinding.inflate(LayoutInflater.from(context));
|
||||||
popupAddFilterBinding.actionHide.setChecked(false);
|
keywordsLayoutBinding.keywordPhrase.setText(filterKeyword.keyword);
|
||||||
} else {
|
keywordsLayoutBinding.wholeWord.setChecked(filterKeyword.whole_word);
|
||||||
popupAddFilterBinding.actionRemove.setChecked(false);
|
keywordsLayoutBinding.deleteKeyword.setOnClickListener(v -> popupAddFilterBinding.keywordsContainer.removeView(keywordsLayoutBinding.deleteKeyword));
|
||||||
popupAddFilterBinding.actionHide.setChecked(true);
|
popupAddFilterBinding.keywordsContainer.addView(keywordsLayoutBinding.getRoot());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
//Add at least a view
|
||||||
|
KeywordsLayoutBinding keywordsLayoutBinding = KeywordsLayoutBinding.inflate(LayoutInflater.from(context));
|
||||||
|
keywordsLayoutBinding.deleteKeyword.setOnClickListener(v -> popupAddFilterBinding.keywordsContainer.removeView(keywordsLayoutBinding.deleteKeyword));
|
||||||
|
popupAddFilterBinding.keywordsContainer.addView(keywordsLayoutBinding.getRoot());
|
||||||
}
|
}
|
||||||
popupAddFilterBinding.actionRemove.setOnClickListener(v -> {
|
popupAddFilterBinding.actionRemove.setOnClickListener(v -> {
|
||||||
popupAddFilterBinding.actionHide.setChecked(false);
|
popupAddFilterBinding.actionHide.setChecked(false);
|
||||||
|
@ -149,15 +165,33 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
|
||||||
|
|
||||||
Button button = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
Button button = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
||||||
button.setOnClickListener(view -> {
|
button.setOnClickListener(view -> {
|
||||||
if (popupAddFilterBinding.addPhrase.getText() == null || popupAddFilterBinding.addPhrase.getText().toString().trim().length() == 0) {
|
|
||||||
popupAddFilterBinding.addPhrase.setError(context.getString(R.string.cannot_be_empty));
|
int keywordsItem = popupAddFilterBinding.keywordsContainer.getChildCount();
|
||||||
return;
|
List<Filter.KeywordsAttributes> keywordsAttributes = null;
|
||||||
|
boolean canBeSent = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < keywordsItem; i++) {
|
||||||
|
View itemView = popupAddFilterBinding.keywordsContainer.getChildAt(i);
|
||||||
|
AppCompatEditText keyword = itemView.findViewById(R.id.keyword_phrase);
|
||||||
|
AppCompatCheckBox whole_word = itemView.findViewById(R.id.whole_word);
|
||||||
|
keywordsAttributes = new ArrayList<>();
|
||||||
|
if (keyword != null && whole_word != null) {
|
||||||
|
Filter.KeywordsAttributes keywordsAttr = new Filter.KeywordsAttributes();
|
||||||
|
keywordsAttr.keyword = keyword.getText().toString();
|
||||||
|
keywordsAttr.whole_word = whole_word.isChecked();
|
||||||
|
if (keywordsAttr.keyword.trim().isEmpty()) {
|
||||||
|
keyword.setError(context.getString(R.string.cannot_be_empty));
|
||||||
|
canBeSent = false;
|
||||||
|
}
|
||||||
|
keywordsAttributes.add(keywordsAttr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!popupAddFilterBinding.contextConversation.isChecked() && !popupAddFilterBinding.contextHome.isChecked() && !popupAddFilterBinding.contextPublic.isChecked() && !popupAddFilterBinding.contextNotification.isChecked() && !popupAddFilterBinding.contextProfiles.isChecked()) {
|
if (!popupAddFilterBinding.contextConversation.isChecked() && !popupAddFilterBinding.contextHome.isChecked() && !popupAddFilterBinding.contextPublic.isChecked() && !popupAddFilterBinding.contextNotification.isChecked() && !popupAddFilterBinding.contextProfiles.isChecked()) {
|
||||||
popupAddFilterBinding.contextDescription.setError(context.getString(R.string.cannot_be_empty));
|
popupAddFilterBinding.contextDescription.setError(context.getString(R.string.cannot_be_empty));
|
||||||
return;
|
canBeSent = false;
|
||||||
}
|
}
|
||||||
if (popupAddFilterBinding.addPhrase.getText() != null && popupAddFilterBinding.addPhrase.getText().toString().trim().length() > 0) {
|
if (canBeSent) {
|
||||||
Filter filterSent = new Filter();
|
Filter filterSent = new Filter();
|
||||||
ArrayList<String> contextFilter = new ArrayList<>();
|
ArrayList<String> contextFilter = new ArrayList<>();
|
||||||
if (popupAddFilterBinding.contextHome.isChecked())
|
if (popupAddFilterBinding.contextHome.isChecked())
|
||||||
|
@ -171,15 +205,19 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
|
||||||
if (popupAddFilterBinding.contextProfiles.isChecked())
|
if (popupAddFilterBinding.contextProfiles.isChecked())
|
||||||
contextFilter.add("account");
|
contextFilter.add("account");
|
||||||
filterSent.context = contextFilter;
|
filterSent.context = contextFilter;
|
||||||
filterSent.expires_at_sent = expire[0];
|
if (expire[0] != -1) {
|
||||||
filterSent.phrase = popupAddFilterBinding.addPhrase.getText().toString();
|
Calendar calendar = Calendar.getInstance();
|
||||||
filterSent.whole_word = popupAddFilterBinding.contextWholeWord.isChecked();
|
calendar.add(Calendar.SECOND, expire[0]);
|
||||||
filterSent.irreversible = popupAddFilterBinding.actionRemove.isChecked();
|
filterSent.expires_at = calendar.getTime();
|
||||||
|
} else {
|
||||||
|
filterSent.expires_at = null;
|
||||||
|
}
|
||||||
|
filterSent.filter_action = popupAddFilterBinding.actionHide.isChecked() ? "hide" : "warn";
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
accountsVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filter.id, filterSent.phrase, filterSent.context, filterSent.irreversible, filterSent.whole_word, filterSent.expires_at_sent)
|
filtersVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filter.id, filterSent.title, filterSent.expires_at, filterSent.context, filterSent.filter_action, keywordsAttributes)
|
||||||
.observe((LifecycleOwner) context, listener::callback);
|
.observe((LifecycleOwner) context, listener::callback);
|
||||||
} else {
|
} else {
|
||||||
accountsVM.addFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterSent.phrase, filterSent.context, filterSent.irreversible, filterSent.whole_word, filterSent.expires_at_sent)
|
filtersVM.addFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterSent.title, filterSent.expires_at, filterSent.context, filterSent.filter_action, keywordsAttributes)
|
||||||
.observe((LifecycleOwner) context, listener::callback);
|
.observe((LifecycleOwner) context, listener::callback);
|
||||||
}
|
}
|
||||||
alertDialog.dismiss();
|
alertDialog.dismiss();
|
||||||
|
@ -192,7 +230,7 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
|
||||||
alertDialog.setOnDismissListener(dialogInterface -> {
|
alertDialog.setOnDismissListener(dialogInterface -> {
|
||||||
//Hide keyboard
|
//Hide keyboard
|
||||||
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
imm.hideSoftInputFromWindow(popupAddFilterBinding.addPhrase.getWindowToken(), 0);
|
imm.hideSoftInputFromWindow(popupAddFilterBinding.addTitle.getWindowToken(), 0);
|
||||||
});
|
});
|
||||||
if (alertDialog.getWindow() != null) {
|
if (alertDialog.getWindow() != null) {
|
||||||
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
||||||
|
@ -213,8 +251,8 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
|
||||||
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.cyanea_primary)));
|
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.cyanea_primary)));
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountsVM accountsVM = new ViewModelProvider(FilterActivity.this).get(AccountsVM.class);
|
FiltersVM filtersVM = new ViewModelProvider(FilterActivity.this).get(FiltersVM.class);
|
||||||
accountsVM.getFilters(BaseMainActivity.currentInstance, BaseMainActivity.currentToken)
|
filtersVM.getFilters(BaseMainActivity.currentInstance, BaseMainActivity.currentToken)
|
||||||
.observe(FilterActivity.this, filters -> {
|
.observe(FilterActivity.this, filters -> {
|
||||||
BaseMainActivity.mainFilters = filters;
|
BaseMainActivity.mainFilters = filters;
|
||||||
if (filters != null && filters.size() > 0) {
|
if (filters != null && filters.size() > 0) {
|
||||||
|
|
|
@ -15,6 +15,7 @@ package app.fedilab.android.client.endpoints;
|
||||||
* see <http://www.gnu.org/licenses>. */
|
* see <http://www.gnu.org/licenses>. */
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import app.fedilab.android.client.entities.api.Filter;
|
import app.fedilab.android.client.entities.api.Filter;
|
||||||
|
@ -49,7 +50,7 @@ public interface MastodonFiltersService {
|
||||||
Call<Filter> addFilter(
|
Call<Filter> addFilter(
|
||||||
@Header("Authorization") String token,
|
@Header("Authorization") String token,
|
||||||
@Field("title") String title,
|
@Field("title") String title,
|
||||||
@Field("expires_in") Integer expires_in,
|
@Field("expires_at") Date expires_at,
|
||||||
@Field("filter_action") String filter_action,
|
@Field("filter_action") String filter_action,
|
||||||
@Field("context[]") List<String> context,
|
@Field("context[]") List<String> context,
|
||||||
@Field("keywords_attributes") List<Filter.KeywordsAttributes> keywordsAttributes
|
@Field("keywords_attributes") List<Filter.KeywordsAttributes> keywordsAttributes
|
||||||
|
@ -62,7 +63,7 @@ public interface MastodonFiltersService {
|
||||||
@Header("Authorization") String token,
|
@Header("Authorization") String token,
|
||||||
@Path("id") String id,
|
@Path("id") String id,
|
||||||
@Field("title") String title,
|
@Field("title") String title,
|
||||||
@Field("expires_in") Integer expires_in,
|
@Field("expires_at") Date expires_at,
|
||||||
@Field("filter_action") String filter_action,
|
@Field("filter_action") String filter_action,
|
||||||
@Field("context[]") List<String> context,
|
@Field("context[]") List<String> context,
|
||||||
@Field("keywords_attributes") List<Filter.KeywordsAttributes> keywordsAttributes
|
@Field("keywords_attributes") List<Filter.KeywordsAttributes> keywordsAttributes
|
||||||
|
|
|
@ -24,12 +24,10 @@ import java.util.List;
|
||||||
public class Filter implements Serializable {
|
public class Filter implements Serializable {
|
||||||
@SerializedName("id")
|
@SerializedName("id")
|
||||||
public String id;
|
public String id;
|
||||||
@SerializedName("phrase")
|
@SerializedName("title")
|
||||||
public String phrase;
|
public String title;
|
||||||
@SerializedName("context")
|
@SerializedName("context")
|
||||||
public List<String> context;
|
public List<String> context;
|
||||||
@SerializedName("whole_word")
|
|
||||||
public boolean whole_word;
|
|
||||||
@SerializedName("expires_at")
|
@SerializedName("expires_at")
|
||||||
public Date expires_at;
|
public Date expires_at;
|
||||||
@SerializedName("filter_action")
|
@SerializedName("filter_action")
|
||||||
|
|
|
@ -33,12 +33,12 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import app.fedilab.android.BaseMainActivity;
|
import app.fedilab.android.BaseMainActivity;
|
||||||
import app.fedilab.android.client.endpoints.MastodonAccountsService;
|
import app.fedilab.android.client.endpoints.MastodonFiltersService;
|
||||||
import app.fedilab.android.client.entities.api.Filter;
|
import app.fedilab.android.client.entities.api.Filter;
|
||||||
import app.fedilab.android.client.entities.api.Notification;
|
import app.fedilab.android.client.entities.api.Notification;
|
||||||
import app.fedilab.android.client.entities.api.Status;
|
import app.fedilab.android.client.entities.api.Status;
|
||||||
import app.fedilab.android.client.entities.app.Timeline;
|
import app.fedilab.android.client.entities.app.Timeline;
|
||||||
import app.fedilab.android.viewmodel.mastodon.AccountsVM;
|
import app.fedilab.android.viewmodel.mastodon.FiltersVM;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.Response;
|
import retrofit2.Response;
|
||||||
|
@ -47,18 +47,18 @@ import retrofit2.converter.gson.GsonConverterFactory;
|
||||||
|
|
||||||
public class TimelineHelper {
|
public class TimelineHelper {
|
||||||
|
|
||||||
private static MastodonAccountsService init(Context context) {
|
private static MastodonFiltersService initv2(Context context) {
|
||||||
OkHttpClient okHttpClient = new OkHttpClient.Builder()
|
OkHttpClient okHttpClient = new OkHttpClient.Builder()
|
||||||
.readTimeout(60, TimeUnit.SECONDS)
|
.readTimeout(60, TimeUnit.SECONDS)
|
||||||
.connectTimeout(60, TimeUnit.SECONDS)
|
.connectTimeout(60, TimeUnit.SECONDS)
|
||||||
.proxy(Helper.getProxy(context))
|
.proxy(Helper.getProxy(context))
|
||||||
.build();
|
.build();
|
||||||
Retrofit retrofit = new Retrofit.Builder()
|
Retrofit retrofit = new Retrofit.Builder()
|
||||||
.baseUrl("https://" + BaseMainActivity.currentInstance + "/api/v1/")
|
.baseUrl("https://" + BaseMainActivity.currentInstance + "/api/v2/")
|
||||||
.addConverterFactory(GsonConverterFactory.create())
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
.client(okHttpClient)
|
.client(okHttpClient)
|
||||||
.build();
|
.build();
|
||||||
return retrofit.create(MastodonAccountsService.class);
|
return retrofit.create(MastodonFiltersService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,9 +74,9 @@ public class TimelineHelper {
|
||||||
//A security to make sure filters have been fetched before displaying messages
|
//A security to make sure filters have been fetched before displaying messages
|
||||||
List<Status> statusesToRemove = new ArrayList<>();
|
List<Status> statusesToRemove = new ArrayList<>();
|
||||||
if (!BaseMainActivity.filterFetched) {
|
if (!BaseMainActivity.filterFetched) {
|
||||||
MastodonAccountsService mastodonAccountsService = init(context);
|
MastodonFiltersService mastodonFiltersService = initv2(context);
|
||||||
List<Filter> filterList;
|
List<Filter> filterList;
|
||||||
Call<List<Filter>> getFiltersCall = mastodonAccountsService.getFilters(BaseMainActivity.currentToken);
|
Call<List<Filter>> getFiltersCall = mastodonFiltersService.getFilters(BaseMainActivity.currentToken);
|
||||||
if (getFiltersCall != null) {
|
if (getFiltersCall != null) {
|
||||||
try {
|
try {
|
||||||
Response<List<Filter>> getFiltersResponse = getFiltersCall.execute();
|
Response<List<Filter>> getFiltersResponse = getFiltersCall.execute();
|
||||||
|
@ -111,52 +111,55 @@ public class TimelineHelper {
|
||||||
} else {
|
} else {
|
||||||
if (!filter.context.contains("public")) continue;
|
if (!filter.context.contains("public")) continue;
|
||||||
}
|
}
|
||||||
|
if (filter.keywords != null && filter.keywords.size() > 0) {
|
||||||
if (filter.whole_word) {
|
for (Filter.FilterKeyword filterKeyword : filter.keywords) {
|
||||||
Pattern p = Pattern.compile("(^|\\W)(" + Pattern.quote(filter.phrase) + ")($|\\W)", Pattern.CASE_INSENSITIVE);
|
if (filterKeyword.whole_word) {
|
||||||
for (Status status : statuses) {
|
Pattern p = Pattern.compile("(^|\\W)(" + Pattern.quote(filterKeyword.keyword) + ")($|\\W)", Pattern.CASE_INSENSITIVE);
|
||||||
String content;
|
for (Status status : statuses) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
String content;
|
||||||
content = Html.fromHtml(status.reblog != null ? status.reblog.content : status.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
else
|
content = Html.fromHtml(status.reblog != null ? status.reblog.content : status.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||||
content = Html.fromHtml(status.reblog != null ? status.reblog.content : status.content).toString();
|
else
|
||||||
Matcher m = p.matcher(content);
|
content = Html.fromHtml(status.reblog != null ? status.reblog.content : status.content).toString();
|
||||||
if (m.find()) {
|
Matcher m = p.matcher(content);
|
||||||
statusesToRemove.add(status);
|
if (m.find()) {
|
||||||
continue;
|
statusesToRemove.add(status);
|
||||||
}
|
continue;
|
||||||
if (status.spoiler_text != null) {
|
}
|
||||||
String spoilerText;
|
if (status.spoiler_text != null) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
String spoilerText;
|
||||||
spoilerText = Html.fromHtml(status.reblog != null ? status.reblog.spoiler_text : status.spoiler_text, Html.FROM_HTML_MODE_LEGACY).toString();
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
else
|
spoilerText = Html.fromHtml(status.reblog != null ? status.reblog.spoiler_text : status.spoiler_text, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||||
spoilerText = Html.fromHtml(status.reblog != null ? status.reblog.spoiler_text : status.spoiler_text).toString();
|
else
|
||||||
Matcher ms = p.matcher(spoilerText);
|
spoilerText = Html.fromHtml(status.reblog != null ? status.reblog.spoiler_text : status.spoiler_text).toString();
|
||||||
if (ms.find()) {
|
Matcher ms = p.matcher(spoilerText);
|
||||||
statusesToRemove.add(status);
|
if (ms.find()) {
|
||||||
|
statusesToRemove.add(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
for (Status status : statuses) {
|
||||||
} else {
|
String content;
|
||||||
for (Status status : statuses) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
String content;
|
content = Html.fromHtml(status.reblog != null ? status.reblog.content : status.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
else
|
||||||
content = Html.fromHtml(status.reblog != null ? status.reblog.content : status.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
content = Html.fromHtml(status.reblog != null ? status.reblog.content : status.content).toString();
|
||||||
else
|
if (content.contains(filterKeyword.keyword)) {
|
||||||
content = Html.fromHtml(status.reblog != null ? status.reblog.content : status.content).toString();
|
statusesToRemove.add(status);
|
||||||
if (content.contains(filter.phrase)) {
|
continue;
|
||||||
statusesToRemove.add(status);
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.spoiler_text != null) {
|
if (status.spoiler_text != null) {
|
||||||
String spoilerText;
|
String spoilerText;
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
spoilerText = Html.fromHtml(status.reblog != null ? status.reblog.spoiler_text : status.spoiler_text, Html.FROM_HTML_MODE_LEGACY).toString();
|
spoilerText = Html.fromHtml(status.reblog != null ? status.reblog.spoiler_text : status.spoiler_text, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||||
else
|
else
|
||||||
spoilerText = Html.fromHtml(status.reblog != null ? status.reblog.spoiler_text : status.spoiler_text).toString();
|
spoilerText = Html.fromHtml(status.reblog != null ? status.reblog.spoiler_text : status.spoiler_text).toString();
|
||||||
if (spoilerText.contains(filter.phrase)) {
|
if (spoilerText.contains(filterKeyword.keyword)) {
|
||||||
statusesToRemove.add(status);
|
statusesToRemove.add(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,8 +185,8 @@ public class TimelineHelper {
|
||||||
List<Notification> notificationToRemove = new ArrayList<>();
|
List<Notification> notificationToRemove = new ArrayList<>();
|
||||||
if (!BaseMainActivity.filterFetched) {
|
if (!BaseMainActivity.filterFetched) {
|
||||||
try {
|
try {
|
||||||
AccountsVM accountsVM = new ViewModelProvider((ViewModelStoreOwner) context).get(AccountsVM.class);
|
FiltersVM filtersVM = new ViewModelProvider((ViewModelStoreOwner) context).get(FiltersVM.class);
|
||||||
accountsVM.getFilters(BaseMainActivity.currentInstance, BaseMainActivity.currentToken).observe((LifecycleOwner) context, filters -> {
|
filtersVM.getFilters(BaseMainActivity.currentInstance, BaseMainActivity.currentToken).observe((LifecycleOwner) context, filters -> {
|
||||||
BaseMainActivity.filterFetched = true;
|
BaseMainActivity.filterFetched = true;
|
||||||
BaseMainActivity.mainFilters = filters;
|
BaseMainActivity.mainFilters = filters;
|
||||||
});
|
});
|
||||||
|
@ -192,51 +195,81 @@ public class TimelineHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//If there are filters:
|
//If there are filters:
|
||||||
if (BaseMainActivity.mainFilters != null && BaseMainActivity.mainFilters.size() > 0) {
|
if (BaseMainActivity.mainFilters != null && BaseMainActivity.mainFilters.size() > 0 && notifications != null && notifications.size() > 0) {
|
||||||
|
|
||||||
|
//Loop through filters
|
||||||
for (Filter filter : BaseMainActivity.mainFilters) {
|
for (Filter filter : BaseMainActivity.mainFilters) {
|
||||||
if (filter.irreversible) { //Dealt by the server
|
if (filter.expires_at != null && filter.expires_at.before(new Date())) {
|
||||||
|
//Expired filter
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (String filterContext : filter.context) {
|
|
||||||
if (Timeline.TimeLineEnum.NOTIFICATION.getValue().equalsIgnoreCase(filterContext)) {
|
if (!filter.context.contains("notification")) continue;
|
||||||
if (filter.whole_word) {
|
if (filter.keywords != null && filter.keywords.size() > 0) {
|
||||||
Pattern p = Pattern.compile("(^" + Pattern.quote(filter.phrase) + "\\b|\\b" + Pattern.quote(filter.phrase) + "$)", Pattern.CASE_INSENSITIVE);
|
for (Filter.FilterKeyword filterKeyword : filter.keywords) {
|
||||||
|
if (filterKeyword.whole_word) {
|
||||||
|
Pattern p = Pattern.compile("(^|\\W)(" + Pattern.quote(filterKeyword.keyword) + ")($|\\W)", Pattern.CASE_INSENSITIVE);
|
||||||
for (Notification notification : notifications) {
|
for (Notification notification : notifications) {
|
||||||
notification.cached = cached;
|
if (notification.status == null) {
|
||||||
if (notification.status != null) {
|
continue;
|
||||||
String content;
|
}
|
||||||
|
String content;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
|
content = Html.fromHtml(notification.status.reblog != null ? notification.status.reblog.content : notification.status.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||||
|
else
|
||||||
|
content = Html.fromHtml(notification.status.reblog != null ? notification.status.reblog.content : notification.status.content).toString();
|
||||||
|
Matcher m = p.matcher(content);
|
||||||
|
if (m.find()) {
|
||||||
|
notificationToRemove.add(notification);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (notification.status.spoiler_text != null) {
|
||||||
|
String spoilerText;
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
content = Html.fromHtml(notification.status.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
spoilerText = Html.fromHtml(notification.status.reblog != null ? notification.status.reblog.spoiler_text : notification.status.spoiler_text, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||||
else
|
else
|
||||||
content = Html.fromHtml(notification.status.content).toString();
|
spoilerText = Html.fromHtml(notification.status.reblog != null ? notification.status.reblog.spoiler_text : notification.status.spoiler_text).toString();
|
||||||
Matcher m = p.matcher(content);
|
Matcher ms = p.matcher(spoilerText);
|
||||||
if (m.find()) {
|
if (ms.find()) {
|
||||||
notificationToRemove.add(notification);
|
notificationToRemove.add(notification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (Notification notification : notifications) {
|
for (Notification notification : notifications) {
|
||||||
|
if (notification.status == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
String content;
|
String content;
|
||||||
notification.cached = cached;
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
content = Html.fromHtml(notification.status.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
content = Html.fromHtml(notification.status.reblog != null ? notification.status.reblog.content : notification.status.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||||
else
|
else
|
||||||
content = Html.fromHtml(notification.status.content).toString();
|
content = Html.fromHtml(notification.status.reblog != null ? notification.status.reblog.content : notification.status.content).toString();
|
||||||
if (content.contains(filter.phrase)) {
|
if (content.contains(filterKeyword.keyword)) {
|
||||||
notificationToRemove.add(notification);
|
notificationToRemove.add(notification);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notification.status.spoiler_text != null) {
|
||||||
|
String spoilerText;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
|
spoilerText = Html.fromHtml(notification.status.reblog != null ? notification.status.reblog.spoiler_text : notification.status.spoiler_text, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||||
|
else
|
||||||
|
spoilerText = Html.fromHtml(notification.status.reblog != null ? notification.status.reblog.spoiler_text : notification.status.spoiler_text).toString();
|
||||||
|
if (spoilerText.contains(filterKeyword.keyword)) {
|
||||||
|
notificationToRemove.add(notification);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
for (Notification notification : notifications) {
|
|
||||||
notification.cached = cached;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notifications.removeAll(notificationToRemove);
|
if (notifications != null) {
|
||||||
|
notifications.removeAll(notificationToRemove);
|
||||||
|
}
|
||||||
return notifications;
|
return notifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ import app.fedilab.android.activities.FilterActivity;
|
||||||
import app.fedilab.android.client.entities.api.Filter;
|
import app.fedilab.android.client.entities.api.Filter;
|
||||||
import app.fedilab.android.databinding.DrawerFilterBinding;
|
import app.fedilab.android.databinding.DrawerFilterBinding;
|
||||||
import app.fedilab.android.helper.Helper;
|
import app.fedilab.android.helper.Helper;
|
||||||
import app.fedilab.android.viewmodel.mastodon.AccountsVM;
|
import app.fedilab.android.viewmodel.mastodon.FiltersVM;
|
||||||
|
|
||||||
|
|
||||||
public class FilterAdapter extends RecyclerView.Adapter<FilterAdapter.FilterViewHolder> {
|
public class FilterAdapter extends RecyclerView.Adapter<FilterAdapter.FilterViewHolder> {
|
||||||
|
@ -69,8 +69,8 @@ public class FilterAdapter extends RecyclerView.Adapter<FilterAdapter.FilterView
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull FilterViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull FilterViewHolder holder, int position) {
|
||||||
Filter filter = filters.get(position);
|
Filter filter = filters.get(position);
|
||||||
if (filter.phrase != null) {
|
if (filter.title != null) {
|
||||||
holder.binding.filterWord.setText(filter.phrase);
|
holder.binding.filterWord.setText(filter.title);
|
||||||
}
|
}
|
||||||
StringBuilder contextString = new StringBuilder();
|
StringBuilder contextString = new StringBuilder();
|
||||||
if (filter.context != null)
|
if (filter.context != null)
|
||||||
|
@ -79,10 +79,7 @@ public class FilterAdapter extends RecyclerView.Adapter<FilterAdapter.FilterView
|
||||||
holder.binding.filterContext.setText(contextString.toString());
|
holder.binding.filterContext.setText(contextString.toString());
|
||||||
holder.binding.editFilter.setOnClickListener(v -> FilterActivity.addEditFilter(context, filter, filter1 -> {
|
holder.binding.editFilter.setOnClickListener(v -> FilterActivity.addEditFilter(context, filter, filter1 -> {
|
||||||
if (filter1 != null) {
|
if (filter1 != null) {
|
||||||
BaseMainActivity.mainFilters.get(position).phrase = filter1.phrase;
|
|
||||||
BaseMainActivity.mainFilters.get(position).context = filter1.context;
|
BaseMainActivity.mainFilters.get(position).context = filter1.context;
|
||||||
BaseMainActivity.mainFilters.get(position).whole_word = filter1.whole_word;
|
|
||||||
BaseMainActivity.mainFilters.get(position).irreversible = filter1.irreversible;
|
|
||||||
BaseMainActivity.mainFilters.get(position).expires_at = filter1.expires_at;
|
BaseMainActivity.mainFilters.get(position).expires_at = filter1.expires_at;
|
||||||
}
|
}
|
||||||
filterAdapter.notifyItemChanged(position);
|
filterAdapter.notifyItemChanged(position);
|
||||||
|
@ -93,8 +90,8 @@ public class FilterAdapter extends RecyclerView.Adapter<FilterAdapter.FilterView
|
||||||
builder.setMessage(R.string.action_lists_confirm_delete);
|
builder.setMessage(R.string.action_lists_confirm_delete);
|
||||||
builder.setIcon(android.R.drawable.ic_dialog_alert)
|
builder.setIcon(android.R.drawable.ic_dialog_alert)
|
||||||
.setPositiveButton(R.string.yes, (dialog, which) -> {
|
.setPositiveButton(R.string.yes, (dialog, which) -> {
|
||||||
AccountsVM accountsVM = new ViewModelProvider((ViewModelStoreOwner) context).get(AccountsVM.class);
|
FiltersVM filtersVM = new ViewModelProvider((ViewModelStoreOwner) context).get(FiltersVM.class);
|
||||||
accountsVM.removeFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filter.id);
|
filtersVM.removeFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filter.id);
|
||||||
filters.remove(filter);
|
filters.remove(filter);
|
||||||
if (filters.size() == 0) {
|
if (filters.size() == 0) {
|
||||||
delete.allFiltersDeleted();
|
delete.allFiltersDeleted();
|
||||||
|
|
|
@ -25,6 +25,7 @@ import androidx.lifecycle.AndroidViewModel;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -129,24 +130,15 @@ public class FiltersVM extends AndroidViewModel {
|
||||||
/**
|
/**
|
||||||
* Create a filter
|
* Create a filter
|
||||||
*
|
*
|
||||||
* @param phrase Text to be filtered
|
|
||||||
* @param filterContext Array of enumerable strings "home", "notifications", "public", "thread". At least one context must be specified.
|
|
||||||
* @param irreversible Should the server irreversibly drop matching entities from home and notifications?
|
|
||||||
* @param wholeWord Consider word boundaries?
|
|
||||||
* @param expiresIn Number of seconds from now the filter should expire. Otherwise, null for a filter that doesn't expire.
|
|
||||||
* @return {@link LiveData} containing a {@link Filter}
|
* @return {@link LiveData} containing a {@link Filter}
|
||||||
*/
|
*/
|
||||||
public LiveData<Filter> addFilter(@NonNull String instance, String token,
|
public LiveData<Filter> addFilter(@NonNull String instance, String token,
|
||||||
@NonNull String phrase,
|
@NonNull String title, Date expires_at, @NonNull List<String> filterContext, String filter_action, List<Filter.KeywordsAttributes> keywordsAttributes) {
|
||||||
@NonNull List<String> filterContext,
|
|
||||||
boolean irreversible,
|
|
||||||
boolean wholeWord,
|
|
||||||
int expiresIn) {
|
|
||||||
filterMutableLiveData = new MutableLiveData<>();
|
filterMutableLiveData = new MutableLiveData<>();
|
||||||
MastodonFiltersService mastodonFiltersService = initV2(instance);
|
MastodonFiltersService mastodonFiltersService = initV2(instance);
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
Filter filter = null;
|
Filter filter = null;
|
||||||
Call<Filter> addFilterCall = mastodonFiltersService.addFilter(token, phrase, filterContext, irreversible, wholeWord, expiresIn == -1 ? null : expiresIn);
|
Call<Filter> addFilterCall = mastodonFiltersService.addFilter(token, title, expires_at, filter_action, filterContext, keywordsAttributes);
|
||||||
if (addFilterCall != null) {
|
if (addFilterCall != null) {
|
||||||
try {
|
try {
|
||||||
Response<Filter> addFiltersResponse = addFilterCall.execute();
|
Response<Filter> addFiltersResponse = addFilterCall.execute();
|
||||||
|
@ -168,20 +160,14 @@ public class FiltersVM extends AndroidViewModel {
|
||||||
/**
|
/**
|
||||||
* Update a filter
|
* Update a filter
|
||||||
*
|
*
|
||||||
* @param id ID of the filter
|
|
||||||
* @param phrase Text to be filtered
|
|
||||||
* @param filterContext Array of enumerable strings "home", "notifications", "public", "thread". At least one context must be specified.
|
|
||||||
* @param irreversible Should the server irreversibly drop matching entities from home and notifications?
|
|
||||||
* @param wholeWord Consider word boundaries?
|
|
||||||
* @param expiresIn Number of seconds from now the filter should expire. Otherwise, null for a filter that doesn't expire.
|
|
||||||
* @return {@link LiveData} containing a {@link Filter}
|
* @return {@link LiveData} containing a {@link Filter}
|
||||||
*/
|
*/
|
||||||
public LiveData<Filter> editFilter(@NonNull String instance, String token, @NonNull String id, @NonNull String phrase, @NonNull List<String> filterContext, boolean irreversible, boolean wholeWord, int expiresIn) {
|
public LiveData<Filter> editFilter(@NonNull String instance, String token, @NonNull String id, @NonNull String title, Date expires_at, @NonNull List<String> filterContext, String filter_action, List<Filter.KeywordsAttributes> keywordsAttributes) {
|
||||||
filterMutableLiveData = new MutableLiveData<>();
|
filterMutableLiveData = new MutableLiveData<>();
|
||||||
MastodonFiltersService mastodonFiltersService = initV2(instance);
|
MastodonFiltersService mastodonFiltersService = initV2(instance);
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
Filter filter = null;
|
Filter filter = null;
|
||||||
Call<Filter> editFilterCall = mastodonFiltersService.editFilter(token, id, phrase, filterContext, irreversible, wholeWord, expiresIn == -1 ? null : expiresIn);
|
Call<Filter> editFilterCall = mastodonFiltersService.editFilter(token, id, title, expires_at, filter_action, filterContext, keywordsAttributes);
|
||||||
if (editFilterCall != null) {
|
if (editFilterCall != null) {
|
||||||
Log.v(Helper.TAG, "request: " + editFilterCall.request());
|
Log.v(Helper.TAG, "request: " + editFilterCall.request());
|
||||||
try {
|
try {
|
||||||
|
|
30
app/src/main/res/layout/keywords_layout.xml
Normal file
30
app/src/main/res/layout/keywords_layout.xml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatEditText
|
||||||
|
android:id="@+id/keyword_phrase"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:hint="@string/keyword_or_phrase" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatCheckBox
|
||||||
|
android:id="@+id/whole_word"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/delete_keyword"
|
||||||
|
style="@style/Widget.AppCompat.Button.Colored"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:contentDescription="@string/delete_keyword"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/ic_baseline_delete_24" />
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
|
@ -35,6 +35,24 @@
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
android:singleLine="true" />
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/filter_expire" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatSpinner
|
||||||
|
android:id="@+id/filter_expire"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="30dp" />
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -167,6 +185,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/hide_completely"
|
android:text="@string/hide_completely"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
|
android:checked="true"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
@ -178,41 +197,47 @@
|
||||||
|
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
|
|
||||||
|
|
||||||
<com.google.android.material.checkbox.MaterialCheckBox
|
|
||||||
android:id="@+id/context_whole_word"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:checked="true"
|
|
||||||
android:text="@string/context_whole_word"
|
|
||||||
app:buttonTint="@color/cyanea_accent_dark_reference" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="20dp"
|
|
||||||
android:layout_marginLeft="20dp"
|
|
||||||
android:layout_marginEnd="20dp"
|
|
||||||
android:layout_marginRight="20dp"
|
|
||||||
android:text="@string/context_whole_word_explanations"
|
|
||||||
android:textColor="@color/cyanea_accent_dark_reference"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.LinearLayoutCompat
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:hint="@string/keyword_or_phrase" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:layout_width="116dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/context_whole_word" />
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
android:id="@+id/keywords_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/add_keyword"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/filter_expire" />
|
android:layout_gravity="end"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
<androidx.appcompat.widget.AppCompatSpinner
|
android:text="@string/add_keyword"
|
||||||
android:id="@+id/filter_expire"
|
android:textColor="@color/cyanea_accent_dark_reference"
|
||||||
android:layout_width="wrap_content"
|
app:icon="@drawable/ic_baseline_add_24"
|
||||||
android:layout_height="wrap_content"
|
app:iconTint="@color/cyanea_primary_dark_reference"
|
||||||
android:layout_marginStart="30dp" />
|
app:strokeColor="@color/cyanea_accent_dark_reference" />
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
</ScrollView>
|
</ScrollView>
|
|
@ -1997,4 +1997,7 @@
|
||||||
<string name="hide_completely_description">Completely hide the filtered content, behaving as if it did not exist</string>
|
<string name="hide_completely_description">Completely hide the filtered content, behaving as if it did not exist</string>
|
||||||
<string name="context_home_list">Home and lists</string>
|
<string name="context_home_list">Home and lists</string>
|
||||||
<string name="title">Title</string>
|
<string name="title">Title</string>
|
||||||
|
<string name="keyword_or_phrase">Keyword or phrase</string>
|
||||||
|
<string name="delete_keyword">Delete keyword</string>
|
||||||
|
<string name="add_keyword">Add keyword</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue