mirror of
https://codeberg.org/tom79/Fedilab.git
synced 2024-12-24 17:50:04 +02:00
parent
d886693c75
commit
b09e21a589
9 changed files with 246 additions and 106 deletions
|
@ -28,8 +28,6 @@ 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;
|
||||||
|
@ -37,7 +35,6 @@ 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;
|
||||||
|
|
||||||
|
@ -45,11 +42,11 @@ 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.ui.drawer.KeywordAdapter;
|
||||||
import app.fedilab.android.viewmodel.mastodon.FiltersVM;
|
import app.fedilab.android.viewmodel.mastodon.FiltersVM;
|
||||||
|
|
||||||
public class FilterActivity extends BaseActivity implements FilterAdapter.Delete {
|
public class FilterActivity extends BaseActivity implements FilterAdapter.Delete {
|
||||||
|
@ -74,6 +71,7 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
|
||||||
R.array.filter_expire, android.R.layout.simple_spinner_dropdown_item);
|
R.array.filter_expire, android.R.layout.simple_spinner_dropdown_item);
|
||||||
popupAddFilterBinding.filterExpire.setAdapter(adapterResize);
|
popupAddFilterBinding.filterExpire.setAdapter(adapterResize);
|
||||||
final int[] expire = {-1};
|
final int[] expire = {-1};
|
||||||
|
Filter.FilterParams filterParams = new Filter.FilterParams();
|
||||||
popupAddFilterBinding.filterExpire.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
popupAddFilterBinding.filterExpire.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onItemSelected(AdapterView<?> parent1, View view, int position1, long id) {
|
public void onItemSelected(AdapterView<?> parent1, View view, int position1, long id) {
|
||||||
|
@ -107,16 +105,29 @@ 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.getRoot()));
|
|
||||||
keywordsLayoutBinding.deleteKeyword.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(context));
|
|
||||||
popupAddFilterBinding.keywordsContainer.addView(keywordsLayoutBinding.getRoot());
|
|
||||||
});
|
|
||||||
|
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
|
|
||||||
|
filterParams.filter_action = filter.filter_action;
|
||||||
|
filterParams.title = filter.title;
|
||||||
|
// filterParams.expires_in = filter.expires_at;
|
||||||
|
filterParams.context = filter.context;
|
||||||
|
filterParams.id = filter.id;
|
||||||
|
if (filter.keywords != null && filter.keywords.size() > 0) {
|
||||||
|
filterParams.keywords = new ArrayList<>();
|
||||||
|
for (Filter.KeywordsAttributes keywordsAttributes : filter.keywords) {
|
||||||
|
Filter.KeywordsParams keywordsParams = new Filter.KeywordsParams();
|
||||||
|
keywordsParams._destroy = null;
|
||||||
|
keywordsParams.id = keywordsAttributes.id;
|
||||||
|
keywordsParams.keyword = keywordsAttributes.keyword;
|
||||||
|
keywordsParams.whole_word = keywordsAttributes.whole_word;
|
||||||
|
filterParams.keywords.add(keywordsParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
popupAddFilterBinding.addTitle.setText(filter.title);
|
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) {
|
||||||
case "home":
|
case "home":
|
||||||
|
@ -136,29 +147,25 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (filter.keywords != null && filter.keywords.size() > 0) {
|
|
||||||
for (Filter.FilterKeyword filterKeyword : filter.keywords) {
|
|
||||||
KeywordsLayoutBinding keywordsLayoutBinding = KeywordsLayoutBinding.inflate(LayoutInflater.from(context));
|
|
||||||
keywordsLayoutBinding.keywordPhrase.setText(filterKeyword.keyword);
|
|
||||||
keywordsLayoutBinding.wholeWord.setChecked(filterKeyword.whole_word);
|
|
||||||
keywordsLayoutBinding.deleteKeyword.setOnClickListener(v -> popupAddFilterBinding.keywordsContainer.removeView(keywordsLayoutBinding.getRoot()));
|
|
||||||
keywordsLayoutBinding.deleteKeyword.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(context));
|
|
||||||
popupAddFilterBinding.keywordsContainer.addView(keywordsLayoutBinding.getRoot());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (popupAddFilterBinding.keywordsContainer.getChildCount() == 0) {
|
|
||||||
KeywordsLayoutBinding keywordsLayoutBinding = KeywordsLayoutBinding.inflate(LayoutInflater.from(context));
|
|
||||||
keywordsLayoutBinding.deleteKeyword.setOnClickListener(v -> popupAddFilterBinding.keywordsContainer.removeView(keywordsLayoutBinding.getRoot()));
|
|
||||||
keywordsLayoutBinding.deleteKeyword.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(context));
|
|
||||||
popupAddFilterBinding.keywordsContainer.addView(keywordsLayoutBinding.getRoot());
|
|
||||||
}
|
}
|
||||||
|
if (filter.filter_action.equalsIgnoreCase("warn")) {
|
||||||
|
popupAddFilterBinding.actionHide.setChecked(true);
|
||||||
|
popupAddFilterBinding.actionRemove.setChecked(false);
|
||||||
} else {
|
} else {
|
||||||
//Add at least a view
|
popupAddFilterBinding.actionHide.setChecked(false);
|
||||||
KeywordsLayoutBinding keywordsLayoutBinding = KeywordsLayoutBinding.inflate(LayoutInflater.from(context));
|
popupAddFilterBinding.actionRemove.setChecked(true);
|
||||||
keywordsLayoutBinding.deleteKeyword.setOnClickListener(v -> popupAddFilterBinding.keywordsContainer.removeView(keywordsLayoutBinding.getRoot()));
|
|
||||||
keywordsLayoutBinding.deleteKeyword.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(context));
|
|
||||||
popupAddFilterBinding.keywordsContainer.addView(keywordsLayoutBinding.getRoot());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeywordAdapter keywordAdapter = new KeywordAdapter(filterParams.keywords);
|
||||||
|
popupAddFilterBinding.lvKeywords.setAdapter(keywordAdapter);
|
||||||
|
popupAddFilterBinding.lvKeywords.setLayoutManager(new LinearLayoutManager(context));
|
||||||
|
|
||||||
|
popupAddFilterBinding.addKeyword.setOnClickListener(v -> {
|
||||||
|
filterParams.keywords.add(new Filter.KeywordsParams());
|
||||||
|
keywordAdapter.notifyItemInserted(filterParams.keywords.size() - 1);
|
||||||
|
});
|
||||||
|
|
||||||
popupAddFilterBinding.actionRemove.setOnClickListener(v -> {
|
popupAddFilterBinding.actionRemove.setOnClickListener(v -> {
|
||||||
popupAddFilterBinding.actionHide.setChecked(false);
|
popupAddFilterBinding.actionHide.setChecked(false);
|
||||||
popupAddFilterBinding.actionRemove.setChecked(true);
|
popupAddFilterBinding.actionRemove.setChecked(true);
|
||||||
|
@ -170,30 +177,17 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
|
||||||
|
|
||||||
AlertDialog alertDialog = dialogBuilder.setPositiveButton(R.string.validate, null)
|
AlertDialog alertDialog = dialogBuilder.setPositiveButton(R.string.validate, null)
|
||||||
.setNegativeButton(R.string.cancel, null).create();
|
.setNegativeButton(R.string.cancel, null).create();
|
||||||
|
|
||||||
alertDialog.setOnShowListener(dialogInterface -> {
|
alertDialog.setOnShowListener(dialogInterface -> {
|
||||||
|
|
||||||
Button button = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
Button button = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
||||||
button.setOnClickListener(view -> {
|
button.setOnClickListener(view -> {
|
||||||
|
|
||||||
int keywordsItem = popupAddFilterBinding.keywordsContainer.getChildCount();
|
|
||||||
List<Filter.KeywordsAttributes> keywordsAttributes = null;
|
|
||||||
boolean canBeSent = true;
|
boolean canBeSent = true;
|
||||||
|
for (int i = 0; i < filterParams.keywords.size(); i++) {
|
||||||
for (int i = 0; i < keywordsItem; i++) {
|
if (filterParams.keywords.get(i).keyword.trim().isEmpty() && !filterParams.keywords.get(i)._destroy) {
|
||||||
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;
|
canBeSent = false;
|
||||||
}
|
}
|
||||||
keywordsAttributes.add(keywordsAttr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (popupAddFilterBinding.addTitle.getText().toString().trim().isEmpty()) {
|
if (popupAddFilterBinding.addTitle.getText().toString().trim().isEmpty()) {
|
||||||
popupAddFilterBinding.addTitle.setError(context.getString(R.string.cannot_be_empty));
|
popupAddFilterBinding.addTitle.setError(context.getString(R.string.cannot_be_empty));
|
||||||
|
@ -204,33 +198,29 @@ public class FilterActivity extends BaseActivity implements FilterAdapter.Delete
|
||||||
canBeSent = false;
|
canBeSent = false;
|
||||||
}
|
}
|
||||||
if (canBeSent) {
|
if (canBeSent) {
|
||||||
Filter filterSent = new Filter();
|
filterParams.context = new ArrayList<>();
|
||||||
ArrayList<String> contextFilter = new ArrayList<>();
|
|
||||||
if (popupAddFilterBinding.contextHome.isChecked())
|
if (popupAddFilterBinding.contextHome.isChecked())
|
||||||
contextFilter.add("home");
|
filterParams.context.add("home");
|
||||||
if (popupAddFilterBinding.contextPublic.isChecked())
|
if (popupAddFilterBinding.contextPublic.isChecked())
|
||||||
contextFilter.add("public");
|
filterParams.context.add("public");
|
||||||
if (popupAddFilterBinding.contextNotification.isChecked())
|
if (popupAddFilterBinding.contextNotification.isChecked())
|
||||||
contextFilter.add("notifications");
|
filterParams.context.add("notifications");
|
||||||
if (popupAddFilterBinding.contextConversation.isChecked())
|
if (popupAddFilterBinding.contextConversation.isChecked())
|
||||||
contextFilter.add("thread");
|
filterParams.context.add("thread");
|
||||||
if (popupAddFilterBinding.contextProfiles.isChecked())
|
if (popupAddFilterBinding.contextProfiles.isChecked())
|
||||||
contextFilter.add("account");
|
filterParams.context.add("account");
|
||||||
filterSent.context = contextFilter;
|
|
||||||
if (expire[0] != -1) {
|
if (expire[0] != -1) {
|
||||||
Calendar calendar = Calendar.getInstance();
|
filterParams.expires_in = (long) expire[0];
|
||||||
calendar.add(Calendar.SECOND, expire[0]);
|
|
||||||
filterSent.expires_at = calendar.getTime();
|
|
||||||
} else {
|
} else {
|
||||||
filterSent.expires_at = null;
|
filterParams.expires_in = null;
|
||||||
}
|
}
|
||||||
filterSent.title = popupAddFilterBinding.addTitle.getText().toString().trim();
|
filterParams.title = popupAddFilterBinding.addTitle.getText().toString().trim();
|
||||||
filterSent.filter_action = popupAddFilterBinding.actionHide.isChecked() ? "hide" : "warn";
|
filterParams.filter_action = popupAddFilterBinding.actionRemove.isChecked() ? "hide" : "warn";
|
||||||
if (filter != null) {
|
if (filterParams.id != null) {
|
||||||
filtersVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filter.id, filterSent.title, filterSent.expires_at, filterSent.context, filterSent.filter_action, keywordsAttributes)
|
filtersVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams)
|
||||||
.observe((LifecycleOwner) context, listener::callback);
|
.observe((LifecycleOwner) context, listener::callback);
|
||||||
} else {
|
} else {
|
||||||
filtersVM.addFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterSent.title, filterSent.expires_at, filterSent.context, filterSent.filter_action, keywordsAttributes)
|
filtersVM.addFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams)
|
||||||
.observe((LifecycleOwner) context, listener::callback);
|
.observe((LifecycleOwner) context, listener::callback);
|
||||||
}
|
}
|
||||||
alertDialog.dismiss();
|
alertDialog.dismiss();
|
||||||
|
|
|
@ -15,16 +15,17 @@ 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;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
|
import retrofit2.http.Body;
|
||||||
import retrofit2.http.DELETE;
|
import retrofit2.http.DELETE;
|
||||||
import retrofit2.http.Field;
|
import retrofit2.http.Field;
|
||||||
import retrofit2.http.FormUrlEncoded;
|
import retrofit2.http.FormUrlEncoded;
|
||||||
import retrofit2.http.GET;
|
import retrofit2.http.GET;
|
||||||
import retrofit2.http.Header;
|
import retrofit2.http.Header;
|
||||||
|
import retrofit2.http.Headers;
|
||||||
import retrofit2.http.POST;
|
import retrofit2.http.POST;
|
||||||
import retrofit2.http.PUT;
|
import retrofit2.http.PUT;
|
||||||
import retrofit2.http.Path;
|
import retrofit2.http.Path;
|
||||||
|
@ -50,23 +51,28 @@ 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_at") Date expires_at,
|
@Field("expires_in") Long expires_in,
|
||||||
@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.KeywordsParams> keywordsAttributes
|
||||||
);
|
);
|
||||||
|
|
||||||
//Edit a filter
|
//Edit a filter
|
||||||
@FormUrlEncoded
|
@Headers({"Accept: application/json"})
|
||||||
@PUT("filters/{id}")
|
@PUT("filters/{id}")
|
||||||
Call<Filter> editFilter(
|
Call<Filter> editFilter(
|
||||||
@Header("Authorization") String token,
|
@Header("Authorization") String token,
|
||||||
@Path("id") String id,
|
@Path("id") String id,
|
||||||
|
@Body Filter.FilterParams filter
|
||||||
|
/*@Path("id") String id,
|
||||||
@Field("title") String title,
|
@Field("title") String title,
|
||||||
@Field("expires_at") Date expires_at,
|
@Field("expires_in") Date expires_in,
|
||||||
@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> keywords
|
||||||
|
@Field("keywords_attributes[][id]") List<String> keywordId,
|
||||||
|
@Field("keywords_attributes[][keyword]") List<String> keywords,
|
||||||
|
@Field("keywords_attributes[][whole_word]") List<Boolean> wholeWords*/
|
||||||
);
|
);
|
||||||
|
|
||||||
//Remove a filter
|
//Remove a filter
|
||||||
|
@ -77,7 +83,7 @@ public interface MastodonFiltersService {
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//Get a filter with its id
|
//Get a keywords for a filter
|
||||||
@GET("filters/{id}/keywords")
|
@GET("filters/{id}/keywords")
|
||||||
Call<List<Filter.KeywordsAttributes>> getKeywordFilter(
|
Call<List<Filter.KeywordsAttributes>> getKeywordFilter(
|
||||||
@Header("Authorization") String token,
|
@Header("Authorization") String token,
|
||||||
|
@ -90,21 +96,20 @@ public interface MastodonFiltersService {
|
||||||
@Header("Authorization") String token,
|
@Header("Authorization") String token,
|
||||||
@Path("filter_id") String filter_id,
|
@Path("filter_id") String filter_id,
|
||||||
@Path("id") String id,
|
@Path("id") String id,
|
||||||
@Field("keyword") Filter.Keyword keyword
|
@Field("keyword") Filter.KeywordsAttributes keyword
|
||||||
);
|
);
|
||||||
|
|
||||||
//Edit a keyword for a filter
|
//Edit a keyword for a filter
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@PUT("filters/{filter_id}/keywords/{id}")
|
@PUT("filter_keywords/{id}")
|
||||||
Call<Filter.KeywordsAttributes> editKeywordFilter(
|
Call<Filter.KeywordsAttributes> editKeywordFilter(
|
||||||
@Header("Authorization") String token,
|
@Header("Authorization") String token,
|
||||||
@Path("filter_id") String filter_id,
|
|
||||||
@Path("id") String id,
|
@Path("id") String id,
|
||||||
@Field("keyword") Filter.Keyword keyword
|
@Field("keyword") Filter.KeywordsAttributes keyword
|
||||||
);
|
);
|
||||||
|
|
||||||
//Remove a keyword for a filter
|
//Remove a keyword for a filter
|
||||||
@DELETE("filters/keywords/{id}")
|
@DELETE("filter_keywords/{id}")
|
||||||
Call<Void> removeKeywordFilter(
|
Call<Void> removeKeywordFilter(
|
||||||
@Header("Authorization") String token,
|
@Header("Authorization") String token,
|
||||||
@Path("id") String id
|
@Path("id") String id
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package app.fedilab.android.client.entities.api;
|
package app.fedilab.android.client.entities.api;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
@ -33,15 +34,26 @@ public class Filter implements Serializable {
|
||||||
@SerializedName("filter_action")
|
@SerializedName("filter_action")
|
||||||
public String filter_action;
|
public String filter_action;
|
||||||
@SerializedName("keywords")
|
@SerializedName("keywords")
|
||||||
public List<FilterKeyword> keywords;
|
public List<KeywordsAttributes> keywords;
|
||||||
|
|
||||||
public static class FilterKeyword implements Serializable {
|
public static String getValueOf(FilterParams filterParams) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
try {
|
||||||
|
return gson.toJson(filterParams);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class KeywordsAttributes implements Serializable {
|
||||||
@SerializedName("id")
|
@SerializedName("id")
|
||||||
public String id;
|
public String id;
|
||||||
@SerializedName("keyword")
|
@SerializedName("keyword")
|
||||||
public String keyword;
|
public String keyword;
|
||||||
@SerializedName("whole_word")
|
@SerializedName("whole_word")
|
||||||
public boolean whole_word;
|
public Boolean whole_word;
|
||||||
|
@SerializedName("_destroy")
|
||||||
|
public Boolean _destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FilterResult implements Serializable {
|
public static class FilterResult implements Serializable {
|
||||||
|
@ -53,27 +65,35 @@ public class Filter implements Serializable {
|
||||||
public List<String> context;
|
public List<String> context;
|
||||||
@SerializedName("whole_word")
|
@SerializedName("whole_word")
|
||||||
public boolean whole_word;
|
public boolean whole_word;
|
||||||
@SerializedName("expires_at")
|
@SerializedName("expires_in")
|
||||||
public Date expires_at;
|
public Date expires_at;
|
||||||
@SerializedName("filter_action")
|
@SerializedName("filter_action")
|
||||||
public String filter_action;
|
public String filter_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Keyword implements Serializable {
|
public static class FilterParams implements Serializable {
|
||||||
@SerializedName("keyword")
|
@SerializedName("id")
|
||||||
public String keyword;
|
public String id;
|
||||||
@SerializedName("whole_word")
|
@SerializedName("title")
|
||||||
public boolean whole_word;
|
public String title;
|
||||||
|
@SerializedName("context")
|
||||||
|
public List<String> context;
|
||||||
|
@SerializedName("expires_in")
|
||||||
|
public Long expires_in;
|
||||||
|
@SerializedName("filter_action")
|
||||||
|
public String filter_action;
|
||||||
|
@SerializedName("keywords_attributes")
|
||||||
|
public List<KeywordsParams> keywords;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class KeywordsAttributes implements Serializable {
|
public static class KeywordsParams implements Serializable {
|
||||||
@SerializedName("id")
|
@SerializedName("id")
|
||||||
public String id;
|
public String id;
|
||||||
@SerializedName("keyword")
|
@SerializedName("keyword")
|
||||||
public String keyword;
|
public String keyword;
|
||||||
@SerializedName("whole_word")
|
@SerializedName("whole_word")
|
||||||
public boolean whole_word;
|
public Boolean whole_word;
|
||||||
@SerializedName("_destroy")
|
@SerializedName("_destroy")
|
||||||
public boolean _destroy;
|
public Boolean _destroy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,8 +92,8 @@ public class Status implements Serializable, Cloneable {
|
||||||
public Card card;
|
public Card card;
|
||||||
@SerializedName("poll")
|
@SerializedName("poll")
|
||||||
public Poll poll;
|
public Poll poll;
|
||||||
@SerializedName("filtered")
|
/* @SerializedName("filtered")
|
||||||
public Filter.FilterResult filtered;
|
public Filter.FilterResult filtered;*/
|
||||||
@SerializedName("pleroma")
|
@SerializedName("pleroma")
|
||||||
public Pleroma pleroma;
|
public Pleroma pleroma;
|
||||||
@SerializedName("cached")
|
@SerializedName("cached")
|
||||||
|
|
|
@ -112,7 +112,7 @@ public class TimelineHelper {
|
||||||
if (!filter.context.contains("public")) continue;
|
if (!filter.context.contains("public")) continue;
|
||||||
}
|
}
|
||||||
if (filter.keywords != null && filter.keywords.size() > 0) {
|
if (filter.keywords != null && filter.keywords.size() > 0) {
|
||||||
for (Filter.FilterKeyword filterKeyword : filter.keywords) {
|
for (Filter.KeywordsAttributes filterKeyword : filter.keywords) {
|
||||||
if (filterKeyword.whole_word) {
|
if (filterKeyword.whole_word) {
|
||||||
Pattern p = Pattern.compile("(^|\\W)(" + Pattern.quote(filterKeyword.keyword) + ")($|\\W)", Pattern.CASE_INSENSITIVE);
|
Pattern p = Pattern.compile("(^|\\W)(" + Pattern.quote(filterKeyword.keyword) + ")($|\\W)", Pattern.CASE_INSENSITIVE);
|
||||||
for (Status status : statuses) {
|
for (Status status : statuses) {
|
||||||
|
@ -206,7 +206,7 @@ public class TimelineHelper {
|
||||||
|
|
||||||
if (!filter.context.contains("notification")) continue;
|
if (!filter.context.contains("notification")) continue;
|
||||||
if (filter.keywords != null && filter.keywords.size() > 0) {
|
if (filter.keywords != null && filter.keywords.size() > 0) {
|
||||||
for (Filter.FilterKeyword filterKeyword : filter.keywords) {
|
for (Filter.KeywordsAttributes filterKeyword : filter.keywords) {
|
||||||
if (filterKeyword.whole_word) {
|
if (filterKeyword.whole_word) {
|
||||||
Pattern p = Pattern.compile("(^|\\W)(" + Pattern.quote(filterKeyword.keyword) + ")($|\\W)", Pattern.CASE_INSENSITIVE);
|
Pattern p = Pattern.compile("(^|\\W)(" + Pattern.quote(filterKeyword.keyword) + ")($|\\W)", Pattern.CASE_INSENSITIVE);
|
||||||
for (Notification notification : notifications) {
|
for (Notification notification : notifications) {
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
package app.fedilab.android.ui.drawer;
|
||||||
|
/* Copyright 2022 Thomas Schneider
|
||||||
|
*
|
||||||
|
* This file is a part of Fedilab
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||||
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||||
|
* see <http://www.gnu.org/licenses>. */
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import app.fedilab.android.R;
|
||||||
|
import app.fedilab.android.client.entities.api.Filter;
|
||||||
|
import app.fedilab.android.databinding.DrawerKeywordBinding;
|
||||||
|
|
||||||
|
public class KeywordAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||||
|
private final List<Filter.KeywordsParams> keywordsParamsList;
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
public KeywordAdapter(List<Filter.KeywordsParams> keywordsParamsList) {
|
||||||
|
this.keywordsParamsList = keywordsParamsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return keywordsParamsList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Filter.KeywordsParams getItem(int position) {
|
||||||
|
return keywordsParamsList.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
context = parent.getContext();
|
||||||
|
DrawerKeywordBinding itemBinding = DrawerKeywordBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||||
|
return new KeywordViewHolder(itemBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
||||||
|
Filter.KeywordsParams keywordsParams = keywordsParamsList.get(position);
|
||||||
|
KeywordViewHolder holder = (KeywordViewHolder) viewHolder;
|
||||||
|
holder.binding.keywordPhrase.setText(keywordsParams.keyword);
|
||||||
|
holder.binding.keywordPhrase.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||||
|
keywordsParams.keyword = charSequence.toString().trim();
|
||||||
|
if (charSequence.toString().length() == 0) {
|
||||||
|
holder.binding.wholeWord.setError(context.getString(R.string.cannot_be_empty));
|
||||||
|
} else {
|
||||||
|
holder.binding.wholeWord.setError(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable editable) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (keywordsParams._destroy != null) {
|
||||||
|
holder.binding.mainContainer.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
holder.binding.mainContainer.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
holder.binding.wholeWord.setOnCheckedChangeListener((compoundButton, checked) -> keywordsParams.whole_word = checked);
|
||||||
|
holder.binding.wholeWord.setChecked(keywordsParams.whole_word != null && keywordsParams.whole_word);
|
||||||
|
holder.binding.deleteKeyword.setOnClickListener(v -> {
|
||||||
|
//The keyword exists
|
||||||
|
if (keywordsParams.id != null) {
|
||||||
|
keywordsParams._destroy = true;
|
||||||
|
notifyItemChanged(position);
|
||||||
|
} else { //It is currently only the app
|
||||||
|
if (keywordsParamsList.size() > position) {
|
||||||
|
keywordsParamsList.remove(position);
|
||||||
|
notifyItemRemoved(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return keywordsParamsList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class KeywordViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
DrawerKeywordBinding binding;
|
||||||
|
|
||||||
|
KeywordViewHolder(DrawerKeywordBinding itemView) {
|
||||||
|
super(itemView.getRoot());
|
||||||
|
binding = itemView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,14 +18,12 @@ package app.fedilab.android.viewmodel.mastodon;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.lifecycle.AndroidViewModel;
|
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;
|
||||||
|
|
||||||
|
@ -60,7 +58,8 @@ public class FiltersVM extends AndroidViewModel {
|
||||||
private MastodonFiltersService initV2(String instance) {
|
private MastodonFiltersService initV2(String instance) {
|
||||||
Retrofit retrofit = new Retrofit.Builder()
|
Retrofit retrofit = new Retrofit.Builder()
|
||||||
.baseUrl("https://" + instance + "/api/v2/")
|
.baseUrl("https://" + instance + "/api/v2/")
|
||||||
.addConverterFactory(GsonConverterFactory.create(Helper.getDateBuilder()))
|
// .addConverterFactory(GsonConverterFactory.create(Helper.getDateBuilder()))
|
||||||
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
.client(okHttpClient)
|
.client(okHttpClient)
|
||||||
.build();
|
.build();
|
||||||
return retrofit.create(MastodonFiltersService.class);
|
return retrofit.create(MastodonFiltersService.class);
|
||||||
|
@ -132,13 +131,12 @@ public class FiltersVM extends AndroidViewModel {
|
||||||
*
|
*
|
||||||
* @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 Filter.FilterParams filterParams) {
|
||||||
@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> addFilterCall = mastodonFiltersService.addFilter(token, title, expires_at, filter_action, filterContext, keywordsAttributes);
|
Call<Filter> addFilterCall = mastodonFiltersService.addFilter(token, filterParams.title, filterParams.expires_in, filterParams.filter_action, filterParams.context, filterParams.keywords);
|
||||||
if (addFilterCall != null) {
|
if (addFilterCall != null) {
|
||||||
try {
|
try {
|
||||||
Response<Filter> addFiltersResponse = addFilterCall.execute();
|
Response<Filter> addFiltersResponse = addFilterCall.execute();
|
||||||
|
@ -162,14 +160,22 @@ public class FiltersVM extends AndroidViewModel {
|
||||||
*
|
*
|
||||||
* @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 title, Date expires_at, @NonNull List<String> filterContext, String filter_action, List<Filter.KeywordsAttributes> keywordsAttributes) {
|
public LiveData<Filter> editFilter(@NonNull String instance, String token, @NonNull Filter.FilterParams filterParams) {
|
||||||
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, title, expires_at, filter_action, filterContext, keywordsAttributes);
|
/* List<String> keywordsId = new ArrayList<>();
|
||||||
|
List<String> keywords = new ArrayList<>();
|
||||||
|
List<Boolean> whole_words = new ArrayList<>();
|
||||||
|
for(Filter.KeywordsAttributes attributes: keywordsAttributes) {
|
||||||
|
keywordsId.add(attributes.id);
|
||||||
|
keywords.add(attributes.keyword);
|
||||||
|
whole_words.add(attributes.whole_word);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
Call<Filter> editFilterCall = mastodonFiltersService.editFilter(token, filterParams.id, filterParams);
|
||||||
if (editFilterCall != null) {
|
if (editFilterCall != null) {
|
||||||
Log.v(Helper.TAG, "request: " + editFilterCall.request());
|
|
||||||
try {
|
try {
|
||||||
Response<Filter> editFiltersResponse = editFilterCall.execute();
|
Response<Filter> editFiltersResponse = editFilterCall.execute();
|
||||||
if (editFiltersResponse.isSuccessful()) {
|
if (editFiltersResponse.isSuccessful()) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/main_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginTop="5dp"
|
|
@ -218,11 +218,10 @@
|
||||||
android:hint="@string/context_whole_word" />
|
android:hint="@string/context_whole_word" />
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
<androidx.appcompat.widget.LinearLayoutCompat
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/keywords_container"
|
android:id="@+id/lv_keywords"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content" />
|
||||||
android:orientation="vertical" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/add_keyword"
|
android:id="@+id/add_keyword"
|
||||||
|
|
Loading…
Reference in a new issue